This is a full reproduction of the study’s results.

 

For more details see:

Citation

………….

………….


Population and Study’s Sample

Total ICU stays in mimic:

dbGetQuery(con, "SELECT count(*) FROM `physionet-data.mimiciv_icu.icustays`")
## # A tibble: 1 × 1
##     f0_
##   <int>
## 1 73181

 

ICU stays with UO records (eligible):

n_distinct(raw_uo$STAY_ID)
## [1] 70364


Hospital admissions with UO records:

n_distinct(raw_uo$HADM_ID)
## [1] 64110

 

Patients with UO records:

n_distinct(raw_uo$SUBJECT_ID)
## [1] 49950

 

Count all UO records (before exclusions):

all_rows_count <- nrow(raw_uo)
all_rows_count
## [1] 3335985

 

Figure for Raw UO Records Data

Frequency of urine output charting by source

S3a <- raw_uo %>% 
  mutate(
    LABEL = case_when(
      LABEL == "GU Irrigant/Urine Volume Out" ~ "GU Irrig. Out",
      LABEL == "GU Irrigant Volume In" ~ "GU Irrig. In",
      .default = LABEL
    )
  ) %>% count(LABEL, sort = TRUE) %>%
   ggplot(aes(x=reorder(LABEL, -n), y=n)) +
   geom_bar(stat="identity") +
   xlab("") +
   ylab("") +
   geom_bar(stat="identity", fill="steelblue") +
   geom_text(aes(label=n), vjust=-0.6, color="black", size=3) +
   theme_classic() +
   theme(axis.text.y=element_blank()) +
   theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
       theme(
         plot.title = element_text(color = "#0099F8", size = 16, face = "bold"),
         plot.subtitle = element_text(size = 10, face = "bold"),
         plot.caption = element_text(face = "italic")
       )

S3a

 

Duplication Analysis

Check for Distinctiveness

First, we are basing distinctive rows in the raw UO data.

Count distinct raw rows:

distinct_time_item_patient_rows_count <- raw_uo %>% 
  select(-VALUE, 
         -SERVICE, 
         -LABEL) %>% 
  n_distinct()

distinct_time_item_patient_rows_count
## [1] 3335985

Conclusion: the original raw query does not have duplicates (all rows are distinct by all columns)

 

Check for Simultaneous Charting

raw_uo_excluions_duplicates$same_value <- as.factor(raw_uo_excluions_duplicates$same_value)
raw_uo_excluions_duplicates$label <- as.factor(raw_uo_excluions_duplicates$label)
raw_uo_excluions_duplicates$label <- factor(raw_uo_excluions_duplicates$label, levels = as.factor(names(sort(table(raw_uo_excluions_duplicates$label),
                                  decreasing = TRUE))))

S4_a <- raw_uo_excluions_duplicates %>%
  select(same_value, label) %>%
  tbl_summary(by = same_value)

S4_a
Characteristic Different volume, N = 12,0511 Equal volume, N = 5181
label

    GU Irrigant Volume In,GU Irrigant/Urine Volume Out 4,189 (35%) 8 (1.5%)
    Foley,L Nephrostomy 1,127 (9.4%) 69 (13%)
    Foley,GU Irrigant Volume In,GU Irrigant/Urine Volume Out 1,158 (9.6%) 3 (0.6%)
    Foley,R Nephrostomy 1,077 (8.9%) 60 (12%)
    R Nephrostomy,L Nephrostomy 988 (8.2%) 125 (24%)
    Foley,Void 703 (5.8%) 61 (12%)
    Foley,Suprapubic 557 (4.6%) 55 (11%)
    R Nephrostomy,Ileoconduit 346 (2.9%) 24 (4.6%)
    Foley,R Nephrostomy,L Nephrostomy 322 (2.7%) 4 (0.8%)
    Foley,GU Irrigant Volume In 186 (1.5%) 1 (0.2%)
    Void,Straight Cath 161 (1.3%) 4 (0.8%)
    Suprapubic,R Nephrostomy 151 (1.3%) 11 (2.1%)
    Foley,Condom Cath 113 (0.9%) 18 (3.5%)
    R Ureteral Stent,Foley 122 (1.0%) 8 (1.5%)
    Suprapubic,L Nephrostomy 120 (1.0%) 9 (1.7%)
    Void,Condom Cath 78 (0.6%) 14 (2.7%)
    L Nephrostomy,Ileoconduit 90 (0.7%) 1 (0.2%)
    R Ureteral Stent,L Ureteral Stent 51 (0.4%) 7 (1.4%)
    Void,L Nephrostomy 48 (0.4%) 7 (1.4%)
    Condom Cath,Straight Cath 47 (0.4%) 2 (0.4%)
    Foley,Ileoconduit 46 (0.4%) 2 (0.4%)
    R Ureteral Stent,L Nephrostomy 45 (0.4%) 2 (0.4%)
    Condom Cath,R Nephrostomy 29 (0.2%) 3 (0.6%)
    R Nephrostomy,L Nephrostomy,Ileoconduit 29 (0.2%) 0 (0%)
    Void,R Nephrostomy 23 (0.2%) 3 (0.6%)
    Condom Cath,Suprapubic 21 (0.2%) 2 (0.4%)
    Foley,Straight Cath 17 (0.1%) 4 (0.8%)
    Foley,GU Irrigant/Urine Volume Out 19 (0.2%) 0 (0%)
    R Ureteral Stent,L Ureteral Stent,L Nephrostomy 19 (0.2%) 0 (0%)
    R Ureteral Stent,R Nephrostomy,Ileoconduit 16 (0.1%) 0 (0%)
    L Ureteral Stent,Foley 14 (0.1%) 1 (0.2%)
    R Ureteral Stent,L Ureteral Stent,Foley 14 (0.1%) 0 (0%)
    R Ureteral Stent,R Nephrostomy 9 (<0.1%) 4 (0.8%)
    Suprapubic,R Nephrostomy,L Nephrostomy 12 (<0.1%) 1 (0.2%)
    Condom Cath,R Nephrostomy,L Nephrostomy 11 (<0.1%) 0 (0%)
    Condom Cath,L Nephrostomy 8 (<0.1%) 2 (0.4%)
    Foley,Suprapubic,R Nephrostomy 10 (<0.1%) 0 (0%)
    Foley,L Nephrostomy,GU Irrigant Volume In 7 (<0.1%) 0 (0%)
    Foley,L Nephrostomy,GU Irrigant Volume In,GU Irrigant/Urine Volume Out 6 (<0.1%) 0 (0%)
    R Nephrostomy,L Nephrostomy,GU Irrigant Volume In,GU Irrigant/Urine Volume Out 6 (<0.1%) 0 (0%)
    L Nephrostomy,GU Irrigant Volume In,GU Irrigant/Urine Volume Out 5 (<0.1%) 0 (0%)
    L Ureteral Stent,R Nephrostomy,L Nephrostomy 5 (<0.1%) 0 (0%)
    Void,R Nephrostomy,L Nephrostomy 5 (<0.1%) 0 (0%)
    R Ureteral Stent,Ileoconduit 4 (<0.1%) 0 (0%)
    Void,Suprapubic 4 (<0.1%) 0 (0%)
    Foley,L Nephrostomy,Ileoconduit 3 (<0.1%) 0 (0%)
    Foley,Void,Condom Cath 1 (<0.1%) 1 (0.2%)
    Ileoconduit,GU Irrigant Volume In,GU Irrigant/Urine Volume Out 2 (<0.1%) 0 (0%)
    R Nephrostomy,L Nephrostomy,GU Irrigant Volume In 2 (<0.1%) 0 (0%)
    R Ureteral Stent,Foley,R Nephrostomy 2 (<0.1%) 0 (0%)
    R Ureteral Stent,Void 2 (<0.1%) 0 (0%)
    Suprapubic,GU Irrigant Volume In,GU Irrigant/Urine Volume Out 2 (<0.1%) 0 (0%)
    Suprapubic,Ileoconduit 1 (<0.1%) 1 (0.2%)
    Void,Ileoconduit 2 (<0.1%) 0 (0%)
    Foley,R Nephrostomy,GU Irrigant Volume In 1 (<0.1%) 0 (0%)
    Foley,R Nephrostomy,Ileoconduit 1 (<0.1%) 0 (0%)
    L Nephrostomy,Straight Cath 1 (<0.1%) 0 (0%)
    L Ureteral Stent,Foley,L Nephrostomy 1 (<0.1%) 0 (0%)
    L Ureteral Stent,L Nephrostomy 1 (<0.1%) 0 (0%)
    L Ureteral Stent,Suprapubic 1 (<0.1%) 0 (0%)
    R Nephrostomy,GU Irrigant Volume In,GU Irrigant/Urine Volume Out 1 (<0.1%) 0 (0%)
    R Nephrostomy,GU Irrigant/Urine Volume Out 1 (<0.1%) 0 (0%)
    R Nephrostomy,L Nephrostomy,GU Irrigant/Urine Volume Out 1 (<0.1%) 0 (0%)
    R Nephrostomy,L Nephrostomy,Straight Cath 1 (<0.1%) 0 (0%)
    R Ureteral Stent,L Ureteral Stent,Foley,Suprapubic 1 (<0.1%) 0 (0%)
    R Ureteral Stent,Straight Cath 1 (<0.1%) 0 (0%)
    Suprapubic,GU Irrigant Volume In 1 (<0.1%) 0 (0%)
    Suprapubic,GU Irrigant/Urine Volume Out 0 (0%) 1 (0.2%)
    Void,Condom Cath,Straight Cath 1 (<0.1%) 0 (0%)
    Void,GU Irrigant Volume In 1 (<0.1%) 0 (0%)
    Void,GU Irrigant Volume In,GU Irrigant/Urine Volume Out 1 (<0.1%) 0 (0%)
1 n (%)
      Show full SQL query —–>
WITH aa AS (
        SELECT
            STAY_ID,
            CHARTTIME
        FROM
            `mimic_uo_and_aki.a_urine_output_raw` uo
        GROUP BY
            STAY_ID,
            CHARTTIME
    ),
    ab AS (
        SELECT
            a.*,
            b.ITEMID,
            b.VALUE,
            c.label
        FROM
            aa a
            LEFT JOIN `mimic_uo_and_aki.a_urine_output_raw` b ON b.STAY_ID = a.STAY_ID
            AND b.CHARTTIME = a.CHARTTIME
            LEFT JOIN `physionet-data.mimiciv_icu.d_items` c ON c.itemid = b.itemid
        ORDER BY
            STAY_ID,
            CHARTTIME,
            ITEMID
    ),
    ac AS (
        SELECT
            STAY_ID,
            CHARTTIME,
            STRING_AGG(label) label,
            COUNT(STAY_ID) COUNT,
            IF(
                MIN(VALUE) = MAX(VALUE),
                "Equal volume",
                "Different volume"
            ) AS same_value
        FROM
            ab
        GROUP BY
            STAY_ID,
            CHARTTIME
    ),
    ad AS (
        SELECT
            COUNT(CHARTTIME) COUNT,
            label,
            same_value
        FROM
            ac
        WHERE
            COUNT > 1
        GROUP BY
            label,
            same_value
    )
SELECT
    *
FROM
    ac
WHERE
    COUNT > 1

In conclusion, most of the records have different values, and thus human error in duplicate record-keeping is not likely.

 

Exclusion

Used for Figure 2. Overview of study’s process.

ICU type exclusion:

dbGetQuery(con, statement = read_file('sql/service_type_exclusion.sql'))
## # A tibble: 1 × 2
##   icu_stays UO_records
##       <int>      <int>
## 1       238       6223
      Show full SQL query —–>
WITH stays_services AS (
    -- Adding ICU type by looking into services
    SELECT
      a.STAY_ID,
      ARRAY_AGG(
        c.curr_service
        ORDER BY
          c.transfertime DESC
        LIMIT
          1
      ) [OFFSET(0)] AS SERVICE
    FROM
      `mimic_uo_and_aki.a_urine_output_raw` a
      LEFT JOIN `physionet-data.mimiciv_hosp.services` c ON c.hadm_id = a.HADM_ID
      AND c.transfertime < DATETIME_ADD(a.CHARTTIME, INTERVAL 1 HOUR)
    GROUP BY
      a.STAY_ID
  )
SELECT
  COUNT(DISTINCT STAY_ID) icu_stays,
  COUNT(STAY_ID) UO_records,
FROM
  `mimic_uo_and_aki.a_urine_output_raw`
WHERE
  STAY_ID NOT IN (
    SELECT
      STAY_ID
    FROM
      stays_services
    WHERE
      SERVICE IN (
        'MED',
        'TSURG',
        'CSURG',
        'CMED',
        'NMED',
        'OMED',
        'TRAUM',
        'SURG',
        'NSURG',
        'ORTHO',
        'VSURG',
        'ENT',
        'PSURG',
        'GU'
      )
  )

 

Uretral stent exclusion:

dbGetQuery(con, statement = read_file('sql/ure_stent_exclusion.sql'))
## # A tibble: 1 × 2
##   icu_stays UO_records
##       <int>      <int>
## 1        45       3201
      Show full SQL query —–>
WITH stays_services AS (
        -- Adding ICU type by looking into services
        SELECT
            a.STAY_ID,
            ARRAY_AGG(
                c.curr_service
                ORDER BY
                    c.transfertime DESC
                LIMIT
                    1
            ) [OFFSET(0)] AS SERVICE
        FROM
            `mimic_uo_and_aki.a_urine_output_raw` a
            LEFT JOIN `physionet-data.mimiciv_hosp.services` c ON c.hadm_id = a.HADM_ID
            AND c.transfertime < DATETIME_ADD(a.CHARTTIME, INTERVAL 1 HOUR)
        GROUP BY
            a.STAY_ID
    )
SELECT
    COUNT(DISTINCT STAY_ID) icu_stays,
    COUNT(STAY_ID) UO_records
FROM
    `mimic_uo_and_aki.a_urine_output_raw`
WHERE
    STAY_ID IN (
        SELECT
            STAY_ID
        FROM
            `physionet-data.mimiciv_icu.outputevents`
        WHERE
            ITEMID IN (226558, 226557) -- Urethral stent
        GROUP BY
            STAY_ID
    )
    AND STAY_ID IN (
        SELECT
            STAY_ID
        FROM
            stays_services
        WHERE
            SERVICE IN (
                'MED',
                'TSURG',
                'CSURG',
                'CMED',
                'NMED',
                'OMED',
                'TRAUM',
                'SURG',
                'NSURG',
                'ORTHO',
                'VSURG',
                'ENT',
                'PSURG',
                'GU'
            )
    )

 

GU irrigation exclusion:

dbGetQuery(con, statement = read_file('sql/gu_irig_exclusion.sql'))
## # A tibble: 1 × 2
##   icu_stays UO_records
##       <int>      <int>
## 1       639      85286
      Show full SQL query —–>
WITH stays_services AS (
    -- Adding ICU type by looking into services
    SELECT
      a.STAY_ID,
      ARRAY_AGG(
        c.curr_service
        ORDER BY
          c.transfertime DESC
        LIMIT
          1
      ) [OFFSET(0)] AS SERVICE
    FROM
      `mimic_uo_and_aki.a_urine_output_raw` a
      LEFT JOIN `physionet-data.mimiciv_hosp.services` c ON c.hadm_id = a.HADM_ID
      AND c.transfertime < DATETIME_ADD(a.CHARTTIME, INTERVAL 1 HOUR)
    GROUP BY
      a.STAY_ID
  )
SELECT
  COUNT(DISTINCT STAY_ID) icu_stays,
  COUNT(STAY_ID) UO_records
FROM
  `mimic_uo_and_aki.a_urine_output_raw`
WHERE
  STAY_ID IN (
    SELECT
      STAY_ID
    FROM
      `physionet-data.mimiciv_icu.outputevents`
    WHERE
      ITEMID IN (227488, 227489) --GU irrigation
    GROUP BY
      STAY_ID
  )
  AND STAY_ID NOT IN (
        SELECT
            STAY_ID
        FROM
            `physionet-data.mimiciv_icu.outputevents`
        WHERE
            ITEMID IN (226558, 226557) -- Urethral stent
        GROUP BY
            STAY_ID
    )
  AND STAY_ID IN (
    SELECT
      STAY_ID
    FROM
      stays_services
    WHERE
      SERVICE IN (
        'MED',
        'TSURG',
        'CSURG',
        'CMED',
        'NMED',
        'OMED',
        'TRAUM',
        'SURG',
        'NSURG',
        'ORTHO',
        'VSURG',
        'ENT',
        'PSURG',
        'GU'
      )
  )
  

 

Not passing sanity check:

dbGetQuery(con, statement = read_file('sql/sanity.sql'))
## # A tibble: 1 × 1
##   UO_records
##        <int>
## 1          9
      Show full SQL query —–>
WITH stays_services AS (
    -- Adding ICU type by looking into services
    SELECT
      a.STAY_ID,
      ARRAY_AGG(
        c.curr_service
        ORDER BY
          c.transfertime DESC
        LIMIT
          1
      ) [OFFSET(0)] AS SERVICE
    FROM
      `mimic_uo_and_aki.a_urine_output_raw` a
      LEFT JOIN `physionet-data.mimiciv_hosp.services` c ON c.hadm_id = a.HADM_ID
      AND c.transfertime < DATETIME_ADD(a.CHARTTIME, INTERVAL 1 HOUR)
    GROUP BY
      a.STAY_ID
  )
SELECT
  COUNT(STAY_ID) UO_records
FROM
  `mimic_uo_and_aki.a_urine_output_raw`
WHERE
  STAY_ID NOT IN (
    SELECT
      STAY_ID
    FROM
      `physionet-data.mimiciv_icu.outputevents`
    WHERE
      ITEMID IN (226558, 226557, 227488, 227489)
    GROUP BY
      STAY_ID
  )
  AND STAY_ID IN (
    SELECT
      STAY_ID
    FROM
      stays_services
    WHERE
      SERVICE IN (
        'MED',
        'TSURG',
        'CSURG',
        'CMED',
        'NMED',
        'OMED',
        'TRAUM',
        'SURG',
        'NSURG',
        'ORTHO',
        'VSURG',
        'ENT',
        'PSURG',
        'GU'
      )
  )
  AND (
    VALUE > 5000
    OR VALUE < 0
  )

 

Total raw urine output after exclusion (“included records, before dropping records without collection times”):

nrow(raw_uo_eligible)
## [1] 3241266
      Show full SQL query —–>
WITH stays_services AS (
    -- Adding ICU type by looking into services
    SELECT
      a.STAY_ID,
      ARRAY_AGG(
        c.curr_service
        ORDER BY
          c.transfertime DESC
        LIMIT
          1
      ) [OFFSET(0)] AS SERVICE
    FROM
      `mimic_uo_and_aki.a_urine_output_raw` a
      LEFT JOIN `physionet-data.mimiciv_hosp.services` c ON c.hadm_id = a.HADM_ID
      AND c.transfertime < DATETIME_ADD(a.CHARTTIME, INTERVAL 1 HOUR)
    GROUP BY
      a.STAY_ID
  )
SELECT
  *
FROM
  `mimic_uo_and_aki.a_urine_output_raw`
WHERE
  STAY_ID NOT IN (
    SELECT
      STAY_ID
    FROM
      `physionet-data.mimiciv_icu.outputevents`
    WHERE
      ITEMID IN (226558, 226557, 227488, 227489)
    GROUP BY
      STAY_ID
  )
  AND STAY_ID IN (
    SELECT
      STAY_ID
    FROM
      stays_services
    WHERE
      SERVICE IN (
        'MED',
        'TSURG',
        'CSURG',
        'CMED',
        'NMED',
        'OMED',
        'TRAUM',
        'SURG',
        'NSURG',
        'ORTHO',
        'VSURG',
        'ENT',
        'PSURG',
        'GU'
      )
  )
  AND NOT (
    VALUE > 5000
    OR VALUE < 0
  )

 

Total icu stays after exclusion (“included records, before dropping records without collection times”):

n_distinct(raw_uo_eligible$STAY_ID)
## [1] 69442

 

Exclusion of first volume in each compartment per ICU stay:

uo_rate_including_null_collection_period %>%
  filter(STAY_ID %in% raw_uo_eligible$STAY_ID) %>%
  filter(is.na(TIME_INTERVAL)) %>%
  nrow()
## [1] 70051

 

UO records with time intervals (“Included records”):

uo_rate_including_null_collection_period %>%
  filter(STAY_ID %in% raw_uo_eligible$STAY_ID) %>%
  drop_na(TIME_INTERVAL) %>%
  nrow()
## [1] 3171215

 

Count UO records by anatomical compartment:

uo_rate %>% 
  mutate(agg_group = case_when(SOURCE == "Foley" |
                                 SOURCE == "Condom Cath" |
                                 SOURCE == "Straight Cath" |
                                 SOURCE == "Suprapubic" |
                                 SOURCE == "Void" ~ "Urinary bladder",
                               TRUE ~ SOURCE)
  ) %>%
           group_by(agg_group) %>%
   dplyr::summarise(N = n()
  )
## # A tibble: 4 × 2
##   agg_group             N
##   <chr>             <int>
## 1 Ileoconduit        6022
## 2 L Nephrostomy      3206
## 3 R Nephrostomy      3465
## 4 Urinary bladder 3158522

 

ICU stays with UO records with time intervals:

print("ICU stays after exclusion criteria:")
## [1] "ICU stays after exclusion criteria:"
uo_rate_including_null_collection_period %>%
  {n_distinct(.$STAY_ID)}
## [1] 69442
print("Included ICU stays (has time intervals):")
## [1] "Included ICU stays (has time intervals):"
uo_rate_including_null_collection_period %>%
                     drop_na(TIME_INTERVAL) %>%
  {n_distinct(.$STAY_ID)}
## [1] 67642
print("ICU stays with UO records that does not  have time interval (no previous UO record in the same compartment:")
## [1] "ICU stays with UO records that does not  have time interval (no previous UO record in the same compartment:"
uo_rate_including_null_collection_period %>%
                     filter(is.na(TIME_INTERVAL)) %>%
  {n_distinct(.$STAY_ID)}
## [1] 69438
print("ICU stays dropped due to no UO records with time intervalst (no previous UO record in the same compartment:")
## [1] "ICU stays dropped due to no UO records with time intervalst (no previous UO record in the same compartment:"
(uo_rate_including_null_collection_period %>%
                     filter(is.na(TIME_INTERVAL))) %>%
  filter(!(STAY_ID %in% (uo_rate_including_null_collection_period %>%
                     drop_na(TIME_INTERVAL))$STAY_ID)) %>%
  {n_distinct(.$STAY_ID)}
## [1] 1800


Count total ICU days of UO monitoring for icu stays with time intervals:

hourly_uo %>%
  filter(STAY_ID %in%
           (uo_rate_including_null_collection_period %>%
                     drop_na(TIME_INTERVAL))$STAY_ID) %>%
  nrow() / 24
## [1] 218388.2

 

Hours of UO monitoring:

print("Hours of UO monitoring in all included ICU stays:")
## [1] "Hours of UO monitoring in all included ICU stays:"
hourly_uo %>%
  filter(STAY_ID %in%
           (
             uo_rate_including_null_collection_period %>%
               drop_na(TIME_INTERVAL)
           )$STAY_ID) %>%
  nrow()
## [1] 5241317
print("Valid hourly-adjusted UO monitoring hours:")
## [1] "Valid hourly-adjusted UO monitoring hours:"
hourly_uo %>%
  filter(STAY_ID %in%
           (
             uo_rate_including_null_collection_period %>%
               drop_na(TIME_INTERVAL)
           )$STAY_ID) %>%
  drop_na(HOURLY_VALID_WEIGHTED_MEAN_RATE) %>%
  nrow()
## [1] 4890186
print("ICU stays with valid hourly-adjusted UO monitoring hours:")
## [1] "ICU stays with valid hourly-adjusted UO monitoring hours:"
hourly_uo %>%
  filter(STAY_ID %in%
           (
             uo_rate_including_null_collection_period %>%
               drop_na(TIME_INTERVAL)
           )$STAY_ID) %>%
  drop_na(HOURLY_VALID_WEIGHTED_MEAN_RATE) %>%
  {n_distinct(.$STAY_ID)}
## [1] 67368


Proportion of valid hours covered out of included hours of uo monitoring:

hourly_uo %>%
  filter(STAY_ID %in%
           (
             uo_rate_including_null_collection_period %>%
               drop_na(TIME_INTERVAL)
           )$STAY_ID) %>%
  drop_na(HOURLY_VALID_WEIGHTED_MEAN_RATE) %>%
  nrow() /
hourly_uo %>%
  filter(STAY_ID %in%
           (
             uo_rate_including_null_collection_period %>%
               drop_na(TIME_INTERVAL)
           )$STAY_ID) %>%
  nrow()
## [1] 0.9330071

 

Hourly-adjusted UO with admission weights:

print("ICU stays with admission weight and valid hourly-adjusted UO:")
## [1] "ICU stays with admission weight and valid hourly-adjusted UO:"
hourly_uo %>%
  filter(STAY_ID %in%
           (
             uo_rate_including_null_collection_period %>%
               drop_na(TIME_INTERVAL)
           )$STAY_ID) %>%
  drop_na(HOURLY_VALID_WEIGHTED_MEAN_RATE, WEIGHT_ADMIT) %>%
  {n_distinct(.$STAY_ID)}
## [1] 65490
print("Valid hourly-adjusted UO monitoring hours with admission weights:")
## [1] "Valid hourly-adjusted UO monitoring hours with admission weights:"
hourly_uo %>%
  filter(STAY_ID %in%
           (
             uo_rate_including_null_collection_period %>%
               drop_na(TIME_INTERVAL)
           )$STAY_ID) %>%
  drop_na(HOURLY_VALID_WEIGHTED_MEAN_RATE, WEIGHT_ADMIT) %>%
  nrow()
## [1] 4812905


ICU stays with calculated KDIGO-UO staging (at least six consecutive hours with valid charting of hourly-adjusted UO)

print("number of ICU stays with valid KDIGO-UO staging")
## [1] "number of ICU stays with valid KDIGO-UO staging"
kdigo_uo_stage %>% 
  filter(stay_id %in%
           (
             uo_rate_including_null_collection_period %>%
               drop_na(TIME_INTERVAL)
           )$STAY_ID) %>%
  {n_distinct(.$stay_id)}
## [1] 65167
print("number of included hours with valid KDIGO-UO staging")
## [1] "number of included hours with valid KDIGO-UO staging"
kdigo_uo_stage %>% 
  filter(stay_id %in%
           (
             uo_rate_including_null_collection_period %>%
               drop_na(TIME_INTERVAL)
           )$STAY_ID) %>%
  nrow()
## [1] 4490878


eligible first ICU admission to each patient for AKI analysis

first_icu_stay <- dbGetQuery(con, "SELECT subject_id,
            ARRAY_AGG(
                STAY_ID
                ORDER BY
                    intime ASC
                LIMIT
                    1
            ) [OFFSET(0)] FIRST_STAY_ID_IN_PATIENT
        FROM
            `physionet-data.mimiciv_icu.icustays`
        GROUP BY
            subject_id")

print("number of first ICU stays with valid KDIGO-UO staging")
## [1] "number of first ICU stays with valid KDIGO-UO staging"
kdigo_uo_stage %>% 
  filter(stay_id %in% first_icu_stay$FIRST_STAY_ID_IN_PATIENT
         & stay_id %in% raw_uo_eligible$STAY_ID) %>%
  {n_distinct(.$stay_id)}
## [1] 46313
print("number of valid hourly KDIGO-UO staging in first ICU stays")
## [1] "number of valid hourly KDIGO-UO staging in first ICU stays"
kdigo_uo_stage %>% 
  filter(stay_id %in% first_icu_stay$FIRST_STAY_ID_IN_PATIENT
         & stay_id %in% raw_uo_eligible$STAY_ID) %>%
  nrow()
## [1] 3075975

included ICU admissions for AKI analysis

print("number of valid hourly KDIGO-UO staging in first ICU stays")
## [1] "number of valid hourly KDIGO-UO staging in first ICU stays"
kdigo_uo_stage %>% 
  filter(stay_id %in% aki_epi$STAY_ID) %>%
  {n_distinct(.$stay_id)}
## [1] 45985

Table 1 - Patient’s characteristics

table_1$SERVICE <- as.factor(table_1$SERVICE)
table_1$admission_age <- as.numeric(table_1$admission_age)
table_1$weight_admit <- as.numeric(table_1$weight_admit)
table_1$height_first <- as.numeric(table_1$height_first)
table_1$creat_first <- as.numeric(table_1$creat_first)

table_1 <- table_1 %>%
  mutate(
    race =
      case_when(
        grepl("asian", race, ignore.case = TRUE) ~ "Asian",
        grepl("black", race, ignore.case = TRUE) ~ "African American",
        grepl("white", race, ignore.case = TRUE) ~ "Caucasian",
        grepl("hispanic", race, ignore.case = TRUE) ~ "Hispanic",
        grepl("other", race, ignore.case = TRUE) ~ "Other",
        grepl("native", race, ignore.case = TRUE) ~ "Other",
        grepl("MULTIPLE", race, ignore.case = TRUE) ~ "Other",
        grepl("PORTUGUESE", race, ignore.case = TRUE) ~ "Other",
        grepl("SOUTH AMERICAN", race, ignore.case = TRUE) ~ "Other",
        TRUE ~ as.character(NA)
      )
  )

uo_for_table1 <- uo_rate_including_null_collection_period %>%
  drop_na(TIME_INTERVAL) %>%
  group_by(STAY_ID) %>%
  summarise(
    count = n(),
    volumes = mean(VALUE, na.rm = TRUE),
    collection_times = mean(TIME_INTERVAL, na.rm = TRUE),
    rates = mean(HOURLY_RATE, na.rm = TRUE),
    validity = mean(if_else(VALIDITY == TRUE, 1, 0)),
    ml_kg_hr = mean(HOURLY_RATE / WEIGHT_ADMIT, na.rm = TRUE)
  )

t1a <- table_1 %>%
  select(
    admission_age,
    weight_admit,
    gender,
    race,
    sofa_first_day,
    charlson_comorbidity_index,
    ckd,
    creat_first,
  # scr_baseline,
    hospital_days,
    icu_days,
    rrt_binary,
    hospital_expire_flag
  ) %>%
  tbl_summary(
    type = list(
      c(hospital_expire_flag,
        ckd,
        rrt_binary) ~ "dichotomous",
      c(admission_age,
        weight_admit,
        creat_first) ~ "continuous"
    ),
    statistic = c(admission_age,
                  weight_admit,
                  creat_first) ~ "{mean} ({sd})",
    missing = "no",
    label = list(
      admission_age ~ "Age at Hospital Admission, years",
      gender ~ "Gender",
      weight_admit ~ "Weight at ICU Admission, kg",
      charlson_comorbidity_index ~ "CCI Score",
      sofa_first_day ~ "SOFA Score at ICU Admission",
      ckd ~ "CKD, Stage 1-4",
      creat_first ~ "First Creatinine, mg/dL",
      race ~ "Ethnicity",
      icu_days ~ "Time in ICU, days",
      hospital_days ~ "Time in hospital, days",
      rrt_binary ~ "Renal replacement therapy",
      hospital_expire_flag ~ "Mortality"
    )
  ) %>%
  add_n() 

display_prec <- function(x)
  mean(x) * 100

t1b <- uo_for_table1 %>%
  select(count,
         volumes,
         validity,
         collection_times,
         rates,
         ml_kg_hr) %>%
  tbl_summary(
    type = list(
      c(volumes,
        collection_times,
        rates,
        ml_kg_hr,
        validity) ~ "continuous"
    ),
    statistic = list(
      c(volumes,
        collection_times,
        rates,
        ml_kg_hr) ~ "{mean} ({sd})",
      validity ~ "{display_prec}%"
    ),
    digits = list(validity ~ 0),
    missing = "no",
    label = list(
      count ~ "Number of Measurements",
      volumes ~ "Average Volumes, mL",
      collection_times ~ "Average Collection Times, minutes",
      validity ~ "Proportion of Valid Records, mean",
      rates ~ "Average Rates, mL/hr",
      ml_kg_hr ~ "Average Rate to Weight, mL/hr/kg"
    )
  ) %>%
  add_n() 

t1c <- tbl1_aki %>%
  select(aki_binary,
         aki_count,
         max_stage,
         aki_portion,
         aki_mean_duration,
         aki_total_time
         ) %>%
  tbl_summary(
    type = list(c(aki_mean_duration,
                  aki_total_time) ~ "continuous"),
    statistic =
      list(
        c(aki_mean_duration,
          aki_total_time) ~ "{mean} ({sd})",
        aki_portion ~ "{display_prec}%"
      ),
    digits = list(aki_portion ~ 0),
    label = list(
      aki_binary ~ "ICU stays with AKI",
      aki_count ~ "Number of AKIs in ICU Stay",
      max_stage ~ "Maximal KDIGO-UO Stage",
      aki_mean_duration ~ "Average AKI Duration, hours",
      aki_total_time ~ "Total Time in AKI, days",
      aki_portion ~ "Proportion of time in AKI, mean"
    ),
    missing = "no"
  ) %>%
  add_n() 

tbl_stack(
  list(t1a, t1b, t1c),
  group_header = c("ICU Stay", "UO Charting Across ICU Stay", "AKI across ICU Stay")
) %>%
  as_gt() %>%
  tab_source_note(source_note = "The variables age at hospital admission, gender, CCI, CKD, ethnicity, time in hospital, and mortality are measured for each hospital admission and might be counted for more than one ICU stay. All other variables are measured individually for each ICU stay. The variables average collection times, average rates, and average rate to weight are only presented for ICU stays with at least two UO measurements for the same compartment, and the latter also required weight at admission. AKI variables were presented for ICU stays with at least one hour with a non-null KDIGO-UO stage. The variables average AKI duration and total time in AKI were specifically reported for ICU stays with at least one AKI event.") %>%
  tab_source_note(source_note = "AKI: Acute Kidney Injury; CCI: Charlson Comorbidity Index; CKD Stage 1-4: Chronic Kidney Disease excluding end-stage-renal-disease; ICU: Intensive Care Unit; KDIGO: Kidney Disease: Improving Global Outcomes; SOFA: Sequential Organ Failure Assessment; UO: Urine Output.")
Characteristic N N = 67,6421
ICU Stay
Age at Hospital Admission, years 67,642 65 (17)
Weight at ICU Admission, kg 65,751 81 (34)
Gender 67,642
    F
29,686 (44%)
    M
37,956 (56%)
Ethnicity 60,412
    African American
6,836 (11%)
    Asian
1,956 (3.2%)
    Caucasian
46,323 (77%)
    Hispanic
2,484 (4.1%)
    Other
2,813 (4.7%)
SOFA Score at ICU Admission 67,642 4 (2, 6)
CCI Score 67,642 5 (3, 7)
CKD, Stage 1-4 13,162 13,162 (100%)
First Creatinine, mg/dL 66,789 1.35 (1.37)
Time in hospital, days 67,642 7 (4, 13)
Time in ICU, days 67,642 2.0 (1.1, 3.8)
Renal replacement therapy 67,642 4,009 (5.9%)
Mortality 67,642 7,198 (11%)
UO Charting Across ICU Stay
Number of Measurements 67,642 23 (10, 50)
Average Volumes, mL 67,642 182 (149)
Proportion of Valid Records, mean 67,642 98%
Average Collection Times, minutes 67,642 157 (230)
Average Rates, mL/hr 67,642 115 (259)
Average Rate to Weight, mL/hr/kg 65,751 1.62 (6.16)
AKI across ICU Stay
ICU stays with AKI 65,167 41,435 (64%)
Number of AKIs in ICU Stay 65,167 1 (0, 2)
Maximal KDIGO-UO Stage 65,167
    0
23,732 (36%)
    1
12,092 (19%)
    2
21,439 (33%)
    3
7,904 (12%)
Proportion of time in AKI, mean 65,167 25%
Average AKI Duration, hours 41,435 11 (15)
Total Time in AKI, days 41,435 1.17 (2.10)
The variables age at hospital admission, gender, CCI, CKD, ethnicity, time in hospital, and mortality are measured for each hospital admission and might be counted for more than one ICU stay. All other variables are measured individually for each ICU stay. The variables average collection times, average rates, and average rate to weight are only presented for ICU stays with at least two UO measurements for the same compartment, and the latter also required weight at admission. AKI variables were presented for ICU stays with at least one hour with a non-null KDIGO-UO stage. The variables average AKI duration and total time in AKI were specifically reported for ICU stays with at least one AKI event.
AKI: Acute Kidney Injury; CCI: Charlson Comorbidity Index; CKD Stage 1-4: Chronic Kidney Disease excluding end-stage-renal-disease; ICU: Intensive Care Unit; KDIGO: Kidney Disease: Improving Global Outcomes; SOFA: Sequential Organ Failure Assessment; UO: Urine Output.
1 Mean (SD); n (%); Median (IQR)

 

Table 2 - UO records characteristics

uo_rate$SOURCE <- as.factor(uo_rate$SOURCE)
uo_rate$VALIDITY <- as.factor(uo_rate$VALIDITY)
uo_rate$SERVICE <- as.factor(uo_rate$SERVICE)

uo_rate %>%
  select(VALUE, TIME_INTERVAL, SOURCE, VALIDITY, SERVICE) %>%
  tbl_summary(by=SERVICE) %>%
  add_overall()
Characteristic Overall, N = 3,171,2151 CMED, N = 285,3741 CSURG, N = 510,7351 ENT, N = 5,9141 GU, N = 6,5621 MED, N = 1,123,0981 NMED, N = 180,2861 NSURG, N = 307,1621 OMED, N = 20,8811 ORTHO, N = 37,7981 PSURG, N = 5,8961 SURG, N = 376,1251 TRAUM, N = 139,7161 TSURG, N = 88,2691 VSURG, N = 83,3991
VALUE 100 (45, 175) 100 (50, 200) 75 (40, 145) 125 (65, 240) 100 (50, 160) 100 (45, 190) 100 (50, 200) 125 (70, 225) 125 (60, 250) 80 (45, 150) 100 (50, 200) 75 (40, 140) 80 (45, 150) 80 (45, 150) 70 (35, 125)
TIME_INTERVAL 60 (60, 120) 60 (60, 120) 60 (60, 60) 60 (60, 120) 60 (60, 120) 60 (60, 120) 60 (60, 120) 60 (60, 120) 90 (60, 120) 60 (60, 82) 60 (60, 120) 60 (60, 81) 60 (60, 60) 60 (60, 71) 60 (60, 60)
SOURCE














    Condom Cath 37,890 (1.2%) 3,977 (1.4%) 2,292 (0.4%) 31 (0.5%) 0 (0%) 10,733 (1.0%) 7,422 (4.1%) 6,957 (2.3%) 598 (2.9%) 67 (0.2%) 22 (0.4%) 2,954 (0.8%) 1,535 (1.1%) 932 (1.1%) 370 (0.4%)
    Foley 2,851,891 (90%) 234,442 (82%) 491,557 (96%) 4,787 (81%) 4,941 (75%) 993,097 (88%) 151,583 (84%) 263,074 (86%) 16,042 (77%) 36,612 (97%) 5,430 (92%) 355,674 (95%) 132,961 (95%) 82,596 (94%) 79,095 (95%)
    Ileoconduit 6,022 (0.2%) 93 (<0.1%) 149 (<0.1%) 0 (0%) 953 (15%) 3,184 (0.3%) 242 (0.1%) 21 (<0.1%) 23 (0.1%) 101 (0.3%) 0 (0%) 1,037 (0.3%) 53 (<0.1%) 1 (<0.1%) 165 (0.2%)
    L Nephrostomy 3,206 (0.1%) 41 (<0.1%) 0 (0%) 0 (0%) 46 (0.7%) 2,377 (0.2%) 48 (<0.1%) 30 (<0.1%) 105 (0.5%) 22 (<0.1%) 0 (0%) 500 (0.1%) 33 (<0.1%) 4 (<0.1%) 0 (0%)
    R Nephrostomy 3,465 (0.1%) 193 (<0.1%) 74 (<0.1%) 0 (0%) 65 (1.0%) 2,642 (0.2%) 60 (<0.1%) 8 (<0.1%) 72 (0.3%) 0 (0%) 0 (0%) 328 (<0.1%) 7 (<0.1%) 4 (<0.1%) 12 (<0.1%)
    Straight Cath 10,207 (0.3%) 280 (<0.1%) 741 (0.1%) 41 (0.7%) 8 (0.1%) 2,458 (0.2%) 2,179 (1.2%) 2,336 (0.8%) 100 (0.5%) 146 (0.4%) 10 (0.2%) 858 (0.2%) 488 (0.3%) 301 (0.3%) 261 (0.3%)
    Suprapubic 9,672 (0.3%) 383 (0.1%) 16 (<0.1%) 0 (0%) 368 (5.6%) 6,965 (0.6%) 203 (0.1%) 329 (0.1%) 4 (<0.1%) 0 (0%) 19 (0.3%) 1,182 (0.3%) 168 (0.1%) 10 (<0.1%) 25 (<0.1%)
    Void 248,862 (7.8%) 45,965 (16%) 15,906 (3.1%) 1,055 (18%) 181 (2.8%) 101,642 (9.1%) 18,549 (10%) 34,407 (11%) 3,937 (19%) 850 (2.2%) 415 (7.0%) 13,592 (3.6%) 4,471 (3.2%) 4,421 (5.0%) 3,471 (4.2%)
VALIDITY














    FALSE 25,128 (0.8%) 2,157 (0.8%) 1,934 (0.4%) 87 (1.5%) 15 (0.2%) 9,900 (0.9%) 3,672 (2.0%) 3,793 (1.2%) 201 (1.0%) 183 (0.5%) 9 (0.2%) 2,085 (0.6%) 436 (0.3%) 212 (0.2%) 444 (0.5%)
    TRUE 3,146,087 (99%) 283,217 (99%) 508,801 (100%) 5,827 (99%) 6,547 (100%) 1,113,198 (99%) 176,614 (98%) 303,369 (99%) 20,680 (99%) 37,615 (100%) 5,887 (100%) 374,040 (99%) 139,280 (100%) 88,057 (100%) 82,955 (99%)
1 Median (IQR); n (%)

 

Data for single patient example

The data that was used for single patient sample in table 1 and figure 6.

Raw UO records:

raw_uo_as_character <- raw_uo %>%
  filter(STAY_ID == 36871275)
raw_uo_as_character[] <- lapply(raw_uo_as_character, as.character)

S2_a <- raw_uo_as_character %>%
  select(-SUBJECT_ID, -HADM_ID, -STAY_ID, -SERVICE) %>%
  arrange(., CHARTTIME) %>%
  slice_head(n=15) %>%
  gt() %>%
  fmt_number(use_seps = TRUE, decimals = 0)

S2_a
CHARTTIME VALUE ITEMID LABEL
2144-05-19 17:00:00 50 226559 Foley
2144-05-19 18:00:00 20 226559 Foley
2144-05-19 19:00:00 20 226559 Foley
2144-05-19 19:46:00 150 226564 R Nephrostomy
2144-05-19 20:00:00 20 226559 Foley
2144-05-19 21:00:00 35 226559 Foley
2144-05-19 22:00:00 45 226564 R Nephrostomy
2144-05-19 22:00:00 35 226559 Foley
2144-05-20 23 226559 Foley
2144-05-20 01:00:00 40 226559 Foley
2144-05-20 01:00:00 35 226564 R Nephrostomy
2144-05-20 02:00:00 17 226559 Foley
2144-05-20 03:00:00 22 226559 Foley
2144-05-20 04:00:00 20 226559 Foley
2144-05-20 05:00:00 50 226559 Foley

 

UO Rates

uo_rate %>%
  filter(STAY_ID == 36871275) %>%
  select(-HADM_ID, -STAY_ID, -WEIGHT_ADMIT, -SERVICE) %>%
  arrange(., CHARTTIME) %>%
  slice_head(n=20) %>%
  gt() %>%
  fmt_number(use_seps = TRUE, decimals = 0)
SOURCE VALUE CHARTTIME LAST_CHARTTIME TIME_INTERVAL VALIDITY HOURLY_RATE
Foley 20 2144-05-19 18:00:00 2144-05-19 17:00:00 60 TRUE 20
Foley 20 2144-05-19 19:00:00 2144-05-19 18:00:00 60 TRUE 20
Foley 20 2144-05-19 20:00:00 2144-05-19 19:00:00 60 TRUE 20
Foley 35 2144-05-19 21:00:00 2144-05-19 20:00:00 60 TRUE 35
R Nephrostomy 45 2144-05-19 22:00:00 2144-05-19 19:46:00 134 TRUE 20
Foley 35 2144-05-19 22:00:00 2144-05-19 21:00:00 60 TRUE 35
Foley 23 2144-05-20 2144-05-19 22:00:00 120 TRUE 12
R Nephrostomy 35 2144-05-20 01:00:00 2144-05-19 22:00:00 180 TRUE 12
Foley 40 2144-05-20 01:00:00 2144-05-20 60 TRUE 40
Foley 17 2144-05-20 02:00:00 2144-05-20 01:00:00 60 TRUE 17
Foley 22 2144-05-20 03:00:00 2144-05-20 02:00:00 60 TRUE 22
Foley 20 2144-05-20 04:00:00 2144-05-20 03:00:00 60 TRUE 20
Foley 50 2144-05-20 05:00:00 2144-05-20 04:00:00 60 TRUE 50
Foley 50 2144-05-20 06:00:00 2144-05-20 05:00:00 60 TRUE 50
Foley 135 2144-05-20 08:00:00 2144-05-20 06:00:00 120 TRUE 68
Foley 65 2144-05-20 10:00:00 2144-05-20 08:00:00 120 TRUE 32
R Nephrostomy 100 2144-05-20 12:00:00 2144-05-20 01:00:00 660 TRUE 9
Foley 60 2144-05-20 12:00:00 2144-05-20 10:00:00 120 TRUE 30
Foley 15 2144-05-20 13:00:00 2144-05-20 12:00:00 60 TRUE 15
Foley 40 2144-05-20 14:00:00 2144-05-20 13:00:00 60 TRUE 40

 

Hourly-Adjusted UO

hourly_uo %>%
  filter(STAY_ID == 36871275) %>%
  select(-STAY_ID, -WEIGHT_ADMIT) %>%
  arrange(., T_PLUS) %>%
  slice_head(n=20) %>%
  gt() %>%
  fmt_number(use_seps = TRUE, decimals = 0)
T_PLUS TIME_INTERVAL_STARTS TIME_INTERVAL_FINISH HOURLY_VALID_WEIGHTED_MEAN_RATE SIMPLE_SUM
1 2144-05-19 17:00:00 2144-05-19 18:00:00 20 20
2 2144-05-19 18:00:00 2144-05-19 19:00:00 20 20
3 2144-05-19 19:00:00 2144-05-19 20:00:00 25 170
4 2144-05-19 20:00:00 2144-05-19 21:00:00 55 35
5 2144-05-19 21:00:00 2144-05-19 22:00:00 55 80
6 2144-05-19 22:00:00 2144-05-19 23:00:00 23 0
7 2144-05-19 23:00:00 2144-05-20 23 23
8 2144-05-20 2144-05-20 01:00:00 52 75
9 2144-05-20 01:00:00 2144-05-20 02:00:00 26 17
10 2144-05-20 02:00:00 2144-05-20 03:00:00 31 22
11 2144-05-20 03:00:00 2144-05-20 04:00:00 29 20
12 2144-05-20 04:00:00 2144-05-20 05:00:00 59 50
13 2144-05-20 05:00:00 2144-05-20 06:00:00 59 50
14 2144-05-20 06:00:00 2144-05-20 07:00:00 77 0
15 2144-05-20 07:00:00 2144-05-20 08:00:00 77 135
16 2144-05-20 08:00:00 2144-05-20 09:00:00 42 0
17 2144-05-20 09:00:00 2144-05-20 10:00:00 42 65
18 2144-05-20 10:00:00 2144-05-20 11:00:00 39 0
19 2144-05-20 11:00:00 2144-05-20 12:00:00 39 160
20 2144-05-20 12:00:00 2144-05-20 13:00:00 33 15

Raw data analysis

Collection Periods

S6_a <- uo_rate %>% group_by(SOURCE) %>%
   dplyr::summarise(N = n(),
                   Mean = round(mean(TIME_INTERVAL),0),
                   SD = round(sd(TIME_INTERVAL),0),
                   '5th' = round(quantile(TIME_INTERVAL, 0.05),0),
                   '10th' = round(quantile(TIME_INTERVAL, 0.1),0),
                   '25th' = round(quantile(TIME_INTERVAL, 0.25),0),
                   '50th' = round(quantile(TIME_INTERVAL, 0.50),0),
                   '75th' = round(quantile(TIME_INTERVAL, 0.75),0),
                   '95th' = round(quantile(TIME_INTERVAL, 0.95),0),
                   Min = round(min(TIME_INTERVAL),0),
                   Max = round(max(TIME_INTERVAL),0)
  ) %>% 
  arrange(desc(N)) %>% 
  gt() %>%
  fmt_number(use_seps = TRUE, decimals = 0)

S6_a
SOURCE N Mean SD 5th 10th 25th 50th 75th 95th Min Max
Foley 2,851,891 83 97 60 60 60 60 105 180 1 43,235
Void 248,862 232 375 60 60 119 180 287 585 1 51,846
Condom Cath 37,890 222 304 60 60 90 131 240 600 1 8,904
Straight Cath 10,207 732 1,486 60 122 300 409 617 2,547 1 35,375
Suprapubic 9,672 115 131 60 60 60 60 120 240 1 6,616
Ileoconduit 6,022 129 213 60 60 60 68 120 300 1 8,040
R Nephrostomy 3,465 223 243 60 60 120 180 240 635 2 7,740
L Nephrostomy 3,206 251 298 60 60 120 180 300 660 2 7,560

Collection Periods:

S6_b <- ggplot(data = uo_rate, aes(x = TIME_INTERVAL / 60)) +
  geom_histogram(binwidth = 1) +
  facet_wrap(~factor(SOURCE, levels=c('Foley', 'Suprapubic', 'Ileoconduit',
                         'Void', 'Condom Cath', 'Straight Cath',
                         'R Nephrostomy', 'L Nephrostomy')), scales = "free") +
  xlim(-1, 20) +
  labs(
          x = "Time interval (hr)",
          y = "Frequency"
        ) +
        theme(
          plot.title = element_text(color = "#0099F8", size = 16, face = "bold"),
          plot.subtitle = element_text(size = 10, face = "bold"),
          plot.caption = element_text(face = "italic")
        )

S6_b

 

Volumes and Collection Periods

S7_a <- uo_rate %>% group_by(SOURCE) %>%
  dplyr::summarise(N = n(),
                   Mean = round(mean(VALUE),0),
                   SD = round(sd(VALUE),0),
                   '5th' = round(quantile(VALUE, 0.05),0),
                   '10th' = round(quantile(VALUE, 0.1),0),
                   '25th' = round(quantile(VALUE, 0.25),0),
                   '50th' = round(quantile(VALUE, 0.50),0),
                   '75th' = round(quantile(VALUE, 0.75),0),
                   '95th' = round(quantile(VALUE, 0.95),0),
                   Min = round(min(VALUE),0),
                   Max = round(max(VALUE),0)
  ) %>% 
  arrange(desc(N)) %>% 
  gt() %>%
  fmt_number(use_seps = TRUE, decimals = 0)

S7_a
SOURCE N Mean SD 5th 10th 25th 50th 75th 95th Min Max
Foley 2,851,891 118 124 15 25 40 80 150 350 0 4,385
Void 248,862 299 195 50 100 160 250 400 700 0 4,500
Condom Cath 37,890 246 205 30 50 100 200 320 625 0 2,900
Straight Cath 10,207 497 271 50 150 320 500 650 1,000 0 2,550
Suprapubic 9,672 126 140 12 25 45 90 150 350 0 2,050
Ileoconduit 6,022 148 149 15 30 50 100 200 400 0 2,500
R Nephrostomy 3,465 157 144 10 20 50 100 220 450 0 1,200
L Nephrostomy 3,206 167 145 10 25 50 125 250 450 0 1,150
S7_b <- ggplot(data = uo_rate, aes(x = VALUE)) +
  facet_wrap(~factor(SOURCE, levels=c('Foley', 'Suprapubic', 'Ileoconduit',
                         'Void', 'Condom Cath', 'Straight Cath',
                         'R Nephrostomy', 'L Nephrostomy')), scales = "free") +
  geom_histogram(binwidth = 50) +
  xlim(-25, 1100) +
  labs(
        # title = "Volumes",
        x = "Volume (ml)",
        y = "Frequency"
      ) +
      theme(
        plot.title = element_text(color = "#0099F8", size = 16, face = "bold"),
        plot.subtitle = element_text(size = 10, face = "bold"),
        plot.caption = element_text(face = "italic")
      )

S7_b

 

Records of zero volume

The proportion of zero value UO measurements:

uo_rate_count <- uo_rate %>% 
  count(SOURCE, sort = TRUE)

uo_rate_0_count <- uo_rate %>% 
  filter(VALUE == 0) %>% 
  count(SOURCE, sort = TRUE)

count_uo_zero_vs_all <- left_join(uo_rate_count, 
                                  uo_rate_0_count, by = "SOURCE") %>% 
  mutate(PROPORTION = n.y / n.x) %>%
  pivot_longer(cols = n.y:n.x, names_to = "type")
  
S7_c <- count_uo_zero_vs_all %>%
  ggplot(aes(x=reorder(SOURCE, -value), y=value, fill=type)) +
    geom_bar(position="fill", stat="identity") +
    xlab("") +
    ylab("") +
    scale_fill_brewer(palette="Paired") +  
    geom_text(aes(label=ifelse(type == "n.y", paste0((round(PROPORTION, 3) * 100), "%"), "")), 
          color="black", 
          size=3, 
          vjust=-1,
          position="fill") +
    theme_minimal() +
    theme(axis.text.y=element_blank()) +
    theme(legend.position="none") +
  theme(axis.text.y=element_blank()) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))+
     labs(
         # title = "Proportion of zero value raw output count",
       ) +
       theme(
         plot.title = element_text(color = "#0099F8", size = 16, face = "bold"),
         plot.subtitle = element_text(size = 10, face = "bold"),
         plot.caption = element_text(face = "italic")
       )
S7_c

uo_rate_0 <- uo_rate %>% filter(VALUE == 0) 
S7_d <- uo_rate_0 %>% group_by(SOURCE) %>%
  dplyr::summarise(N = n(),
                   Mean = round(mean(TIME_INTERVAL),0),
                   SD = round(sd(TIME_INTERVAL),0),
                   '5th' = round(quantile(TIME_INTERVAL, 0.05),0),
                   '10th' = round(quantile(TIME_INTERVAL, 0.1),0),
                   '25th' = round(quantile(TIME_INTERVAL, 0.25),0),
                   '50th' = round(quantile(TIME_INTERVAL, 0.50),0),
                   '75th' = round(quantile(TIME_INTERVAL, 0.75),0),
                   '95th' = round(quantile(TIME_INTERVAL, 0.95),0),
                   Min = round(min(TIME_INTERVAL),0),
                   Max = round(max(TIME_INTERVAL),0)
  ) %>% 
  arrange(desc(N)) %>% 
  gt() %>%
  fmt_number(use_seps = TRUE, decimals = 0)

S7_d
SOURCE N Mean SD 5th 10th 25th 50th 75th 95th Min Max
Foley 31,574 103 232 45 60 60 60 104 240 1 15,007
Void 2,609 412 1,078 39 60 60 180 300 1,440 1 18,747
Condom Cath 651 194 388 51 60 60 120 240 516 1 5,952
Suprapubic 213 222 230 33 60 60 210 240 528 1 2,189
Straight Cath 101 1,013 1,859 60 120 180 303 858 3,508 13 14,427
Ileoconduit 89 216 292 60 60 60 120 240 699 15 1,680
R Nephrostomy 85 275 873 60 60 60 120 180 516 13 7,740
L Nephrostomy 70 258 892 60 60 60 120 220 360 60 7,560

Adjusting for hourly UO

UO Rate

S8_a <- uo_rate %>% group_by(SOURCE) %>%
    dplyr::summarise(N = n(),
                   Mean = round(mean(HOURLY_RATE),0),
                   SD = round(sd(HOURLY_RATE),0),
                   '5th' = round(quantile(HOURLY_RATE, 0.05),0),
                   '10th' = round(quantile(HOURLY_RATE, 0.1),0),
                   '25th' = round(quantile(HOURLY_RATE, 0.25),0),
                   '50th' = round(quantile(HOURLY_RATE, 0.50),0),
                   '75th' = round(quantile(HOURLY_RATE, 0.75),0),
                   '95th' = round(quantile(HOURLY_RATE, 0.95),0),
                   Min = round(min(HOURLY_RATE),0),
                   Max = round(max(HOURLY_RATE),0)
  ) %>% 
  arrange(desc(N)) %>% 
  gt() %>%
  fmt_number(use_seps = TRUE, decimals = 0)

S8_a
SOURCE N Mean SD 5th 10th 25th 50th 75th 95th Min Max
Foley 2,851,891 105 276 11 20 35 62 120 300 0 108,000
Void 248,862 159 639 17 25 50 90 160 400 0 57,000
Condom Cath 37,890 117 309 10 20 40 75 129 325 0 24,000
Straight Cath 10,207 195 1,786 2 11 40 69 114 378 0 114,000
Suprapubic 9,672 89 151 5 15 32 60 100 250 0 6,000
Ileoconduit 6,022 99 179 7 17 38 67 120 262 0 9,000
R Nephrostomy 3,465 65 138 3 7 17 40 75 200 0 6,000
L Nephrostomy 3,206 66 300 3 7 18 38 75 200 0 16,500
S8_b <- ggplot(data = uo_rate, aes(x = HOURLY_RATE)) +
  geom_histogram(binwidth = 20) +
  facet_wrap(~factor(SOURCE, levels=c('Foley', 'Suprapubic', 'Ileoconduit',
                         'Void', 'Condom Cath', 'Straight Cath',
                         'R Nephrostomy', 'L Nephrostomy')), scales = "free") +  xlim(-10, 500) +
  labs(
        # title = "UO Rates",
        # subtitle = "by source",
        x = "Rate (ml/hr)",
        y = "Frequency"
      ) +
      theme(
        plot.title = element_text(color = "#0099F8", size = 16, face = "bold"),
        plot.subtitle = element_text(size = 10, face = "bold"),
        plot.caption = element_text(face = "italic")
      )

S8_b

 

Low UO Rate Analysis

The association between UO rates and collection periods, smoothed conditional means for records of Foley catheter.

S8_d <- uo_rate %>%
  filter(SOURCE == "Foley",
         HOURLY_RATE < 500) %>%
  # slice_head(n = 50000) %>%
  ggplot(aes(x = HOURLY_RATE, y = TIME_INTERVAL)) +
  geom_smooth(se = TRUE, alpha = 0.1, linewidth = 1) +
  geom_smooth(
    se = FALSE,
    method = "lm",
    linetype = "dashed",
    color = "red", 
    linewidth = 0.3
  ) +
  geom_hline(yintercept = 60,
             size = 0.3,
             color = "#cccccc") +
  geom_vline(
    xintercept = 20,
    size = 0.3,
    color = "black",
    linetype = "dotdash"
  ) +
  scale_x_continuous(breaks = c(0, 20, 50, 100, 200, 300, 400, 500)) +
  scale_y_continuous(breaks = c(0, 60, 100, 200)) +
  coord_cartesian(xlim = c(0, 500), ylim = c(0, 200)) +
  labs(x = "Urine output rate (ml/hr)", y = "Collection periods (min)") +
  theme_classic() + # remove panel background and gridlines
  theme(
    plot.title = element_text(
      color = "#0099F8",
      size = 16,
      face = "bold"
    ),
    plot.subtitle = element_text(size = 10, face = "bold"),
    plot.caption = element_text(face = "italic")
  )

S8_d

Quantile analysis for collection periods as a function of rates.

uo_rate_qreg <- uo_rate %>%
  left_join(anchor_year, by = "HADM_ID") %>%
  filter(SOURCE == "Foley",
         HOURLY_RATE < 500,
         ANCHOR_START > 2016) %>%
  slice_head(n = 500000)

#### Quantile
quantile_reg <- rq(TIME_INTERVAL ~
                     HOURLY_RATE,
                   seq(0.10, 0.90, by = 0.10),
                   # c(.05, .1, .25, .5, .75, .90, .95),
                   data = uo_rate_qreg)

# summary(quantile_reg, se = "iid") %>% 
#   plot()
### OLS
lm <- lm(data=uo_rate_qreg,
         formula =  TIME_INTERVAL ~
           HOURLY_RATE)

ols <- as.data.frame(coef(lm))
ols.ci <- as.data.frame(confint(lm, level = 0.95))
ols2 <- cbind(ols, ols.ci)
ols2 <- tibble::rownames_to_column(ols2, var="term")



#### Quantile
S8_e <- quantile_reg %>%
  tidy(se.type = "iid", conf.int = TRUE, conf.level = 0.95) %>%
  filter(!grepl("factor", term)) %>%
  ggplot(aes(x=tau,y=estimate)) +
  theme_classic() +
  theme(
    strip.background = element_blank(),
    #strip.text.x = element_blank()
  ) +
  scale_y_continuous(limits = symmetric_limits) +
  scale_x_continuous(breaks = scales::pretty_breaks(n = 12)) +
  ##### quantilie results
  geom_point(color="#27408b", size = 0.3)+ 
  geom_line(color="black", linetype = "dotdash", size = 0.3)+ 
  geom_ribbon(aes(ymin=conf.low,ymax=conf.high),alpha=0.25, fill="#555555")+
  facet_wrap(~term, scales="free", ncol=1)+
  ##### OLS results
  geom_hline(data = ols2, aes(yintercept= `coef(lm)`), lty=1, color="red", size=0.3)+
  geom_hline(data = ols2, aes(yintercept= `2.5 %`), lty=2, color="red", size=0.3)+
  geom_hline(data = ols2, aes(yintercept= `97.5 %`), lty=2, color="red", size=0.3)+
  #### Lines
   geom_hline(yintercept = 0, size=0.3) 

S8_e

# Visualization for Quantile Regression with some tau values: 
intercept_slope <- quantile_reg %>% 
  coef() %>% 
  t() %>% 
  data.frame() %>% 
  rename(intercept = X.Intercept., slope = HOURLY_RATE) %>% 
  mutate(quantile = row.names(.))


S8_f <-
  ggplot() +
  geom_jitter(data = uo_rate_qreg, aes(HOURLY_RATE, TIME_INTERVAL),
    alpha = 0.2,
    size = 0.5,
    stroke = 0.5,
    width = 2,
    height = 2
  ) +
  geom_abline(data = intercept_slope, aes(
    intercept = intercept,
    slope = slope,
    color = quantile
  ),
  linewidth=1) +
  theme_minimal() +
  labs(x = "Urine output rate (ml/hr)", y = "Collection periods (min)") +
  coord_cartesian(xlim = c(0, 500), ylim = c(0, 500))

S8_f

uo_rate_qreg <- uo_rate %>%
  filter(SOURCE == "Foley") %>%
  arrange(STAY_ID) %>%
  slice_head(n = 500000)

percentile <- ecdf(uo_rate_qreg$TIME_INTERVAL)

#### Quantile
quantile_reg2 <- rq(TIME_INTERVAL ~ HOURLY_RATE, 
                    # seq(0.20, 0.80, by = 0.10), 
                    c(percentile(30),
                      percentile(60) - ((1-percentile(60))/10),
                      percentile(90),
                      percentile(120) - ((1-percentile(120))/10),
                      percentile(150),
                      percentile(180) - ((1-percentile(180))/10),
                      percentile(210),
                      percentile(240) - ((1-percentile(240))/10)),
                    data=uo_rate_qreg)

# Visualization for Quantile Regression with some tau values: 
intercept_slope <- quantile_reg2 %>% 
  coef() %>% 
  t() %>% 
  data.frame() %>% 
  rename(intercept = X.Intercept., slope = HOURLY_RATE) %>% 
  mutate(quantile = row.names(.))


ggplot() + 
  geom_point(data = uo_rate_qreg, aes(HOURLY_RATE, TIME_INTERVAL), 
             alpha = 0.5) + 
  geom_abline(data = intercept_slope, aes(intercept = intercept, slope = slope, color = quantile)) + 
  theme_minimal() + 
  labs(x = "HOURLY_RATE", y = "TIME_INTERVAL", 
       title = "Quantile Regression with tau = 0.25, 0.50 and 0.75", 
       caption = "Data Source: Koenker and Bassett (1982)") +
  coord_cartesian(xlim = c(0, 1000), ylim = c(0, 300))

 

Collection periods for UO rate 20ml/hr or below

uo_rate %>% 
  filter(HOURLY_RATE <= 20) %>%
  group_by(SOURCE) %>%
   dplyr::summarise(N = n(),
                   Mean = round(mean(TIME_INTERVAL),0),
                   SD = round(sd(TIME_INTERVAL),0),
                   '5th' = round(quantile(TIME_INTERVAL, 0.05),0),
                   '10th' = round(quantile(TIME_INTERVAL, 0.1),0),
                   '25th' = round(quantile(TIME_INTERVAL, 0.25),0),
                   '50th' = round(quantile(TIME_INTERVAL, 0.50),0),
                   '75th' = round(quantile(TIME_INTERVAL, 0.75),0),
                   '95th' = round(quantile(TIME_INTERVAL, 0.95),0),
                   Min = round(min(TIME_INTERVAL),0),
                   Max = round(max(TIME_INTERVAL),0)
  ) %>% 
  arrange(desc(N)) %>% 
  gt() %>%
  fmt_number(use_seps = TRUE, decimals = 0)
SOURCE N Mean SD 5th 10th 25th 50th 75th 95th Min Max
Foley 316,355 120 255 60 60 60 60 120 300 1 43,235
Void 16,971 635 1,247 60 120 226 381 700 1,748 1 51,846
Condom Cath 4,191 492 736 60 60 125 240 536 1,620 1 8,904
Straight Cath 1,380 2,761 3,343 240 390 900 1,750 3,191 7,964 13 35,375
Suprapubic 1,355 216 291 60 60 60 120 240 695 1 6,616
R Nephrostomy 1,055 321 377 60 60 120 240 361 850 13 7,740
L Nephrostomy 939 370 489 60 120 120 240 420 923 34 7,560
Ileoconduit 759 280 537 60 60 60 120 240 948 15 8,040
uo_rate %>% 
  filter(HOURLY_RATE <= 20) %>%
ggplot(aes(x = TIME_INTERVAL / 60)) +
  geom_histogram(binwidth = 1) +
  facet_wrap(~factor(SOURCE, levels=c('Foley', 'Suprapubic', 'Ileoconduit',
                         'Void', 'Condom Cath', 'Straight Cath',
                         'R Nephrostomy', 'L Nephrostomy')), scales = "free") +  xlim(-1, 20) +
  labs(
          title = "Collection periods for UO rate 20ml/hr or below",
          subtitle = "by source",
          x = "Time interval (hr)",
          y = "Frequency"
        ) +
        theme(
          plot.title = element_text(color = "#0099F8", size = 16, face = "bold"),
          plot.subtitle = element_text(size = 10, face = "bold"),
          plot.caption = element_text(face = "italic")
        )

 

Mean Rate

Mean UO rate weighted by tyme and grouped by source:

S8_c <- uo_rate_true %>% 
  group_by(SOURCE) %>%
  summarise(weighted_mean_rate = weighted.mean(HOURLY_RATE, TIME_INTERVAL)) %>%
  gt() %>%
  fmt_number(use_seps = TRUE, decimals = 1) %>%
  cols_label(
    SOURCE = "Source",
    weighted_mean_rate = "Weighted mean rate (ml/hr)"
  )

S8_c
Source Weighted mean rate (ml/hr)
Condom Cath 71.5
Foley 88.9
Ileoconduit 76.1
L Nephrostomy 44.8
R Nephrostomy 45.6
Straight Cath 46.6
Suprapubic 70.4
Void 81.7

 

Hourly-adjusted UO

S9_a <- hourly_uo %>% drop_na(HOURLY_VALID_WEIGHTED_MEAN_RATE) %>%
    dplyr::summarise(N = n(),
                   Mean = round(mean(HOURLY_VALID_WEIGHTED_MEAN_RATE),0),
                   SD = round(sd(HOURLY_VALID_WEIGHTED_MEAN_RATE),0),
                   '5th' = round(quantile(HOURLY_VALID_WEIGHTED_MEAN_RATE, 0.05),0),
                   '10th' = round(quantile(HOURLY_VALID_WEIGHTED_MEAN_RATE, 0.1),0),
                   '25th' = round(quantile(HOURLY_VALID_WEIGHTED_MEAN_RATE, 0.25),0),
                   '50th' = round(quantile(HOURLY_VALID_WEIGHTED_MEAN_RATE, 0.50),0),
                   '75th' = round(quantile(HOURLY_VALID_WEIGHTED_MEAN_RATE, 0.75),0),
                   '95th' = round(quantile(HOURLY_VALID_WEIGHTED_MEAN_RATE, 0.95),0),
                   Min = round(min(HOURLY_VALID_WEIGHTED_MEAN_RATE),0),
                   Max = round(max(HOURLY_VALID_WEIGHTED_MEAN_RATE),0)
  ) %>% 
  arrange(desc(N)) %>% 
  gt() %>%
  fmt_number(use_seps = TRUE, decimals = 0)

S9_a
N Mean SD 5th 10th 25th 50th 75th 95th Min Max
4,890,186 86 93 8 16 32 60 100 250 0 4,098
S9_b <- hourly_uo %>% drop_na(HOURLY_VALID_WEIGHTED_MEAN_RATE) %>%
ggplot(aes(x = HOURLY_VALID_WEIGHTED_MEAN_RATE)) +
  geom_histogram(binwidth = 25) +
  xlim(-10, 500) + 
  labs(
        # title = "Hourly-Adjusted UO",
        x = "Hourly UO (ml)",
        y = "Frequency"
      ) +
      theme(
        plot.title = element_text(color = "#0099F8", size = 16, face = "bold"),
        plot.subtitle = element_text(size = 10, face = "bold"),
        plot.caption = element_text(face = "italic")
      )

S9_b

 

Simple Sum Comparison

Showing proportion of hours with less than 100ml difference):

adj_uo_diff <- hourly_uo %>%
  select(HOURLY_VALID_WEIGHTED_MEAN_RATE, SIMPLE_SUM) %>%
  filter(!is.na(HOURLY_VALID_WEIGHTED_MEAN_RATE)) %>%
  mutate(hourly_diff = abs(HOURLY_VALID_WEIGHTED_MEAN_RATE - SIMPLE_SUM)) %>%
  mutate(
    cutoff_10 = if_else(hourly_diff < 10, 1, 0),
    cutoff_50 = if_else(hourly_diff < 50, 1, 0),
    cutoff_100 = if_else(hourly_diff < 100, 1, 0),
    cutoff_150 = if_else(hourly_diff < 150, 1, 0),
    cutoff_200 = if_else(hourly_diff < 200, 1, 0)
  )

my_order <- c("<10", "<50", "<100", "<150", "<200")

S11 <- adj_uo_diff %>%
  select(cutoff_10,
         cutoff_50,
         cutoff_100,
         cutoff_150,
         cutoff_200) %>%
  pivot_longer(cols = contains("cutoff")) %>%
  transmute(name = case_when(
    name == "cutoff_10" ~ "<10",
    name == "cutoff_50" ~ "<50",
    name == "cutoff_100" ~ "<100",
    name == "cutoff_150" ~ "<150",
    name == "cutoff_200" ~ "<200"
  ),
  value) %>%
  group_by(name) %>%
  summarise(agreement = paste0(round(mean(value) * 100, 1), "%"),
            non_agreement = paste0(round((1 - mean(
              value
            )) * 100, 1), "%")) %>%
  arrange(match(name, my_order)) %>%
  gt() %>%
  # tab_header(
  #   title = md("**Comparison of Hourly-Adjusted UO and Simple Summation**"),
  # ) %>%
  cols_label(
    name = "Cut-off (ml)",
    agreement = "Proportion  of Agreement",
    non_agreement = "Proportion  of Disagreement"
  ) %>%
  cols_align(
    align = "center"
  ) %>%
  tab_source_note(source_note = "The table demonstrates the significance of hourly adjustment for accuracy by presenting the variance between the adjusted values and the simple hourly summation. Cut-off values are based on the absolute difference between the hourly-adjusted UO and a simple hourly summation of UO. Measurements charted on the hour were included with the previous time interval. ")

adj_uo_diff <- hourly_uo %>%
  select(HOURLY_VALID_WEIGHTED_MEAN_RATE, SIMPLE_SUM) %>%
  filter(!is.na(HOURLY_VALID_WEIGHTED_MEAN_RATE)) %>%
  mutate(no_diff = 
           ifelse((is.na(HOURLY_VALID_WEIGHTED_MEAN_RATE) &
                  is.na(SIMPLE_SUM)) |
             (!is.na(HOURLY_VALID_WEIGHTED_MEAN_RATE) &
                  !is.na(SIMPLE_SUM) &
                    abs(HOURLY_VALID_WEIGHTED_MEAN_RATE-SIMPLE_SUM) < 100), 
                  1, 
                  0),
         .keep = "none")

S11
Cut-off (ml) Proportion of Agreement Proportion of Disagreement
<10 44.4% 55.6%
<50 65.5% 34.5%
<100 83.7% 16.3%
<150 91.4% 8.6%
<200 95.1% 4.9%
The table demonstrates the significance of hourly adjustment for accuracy by presenting the variance between the adjusted values and the simple hourly summation. Cut-off values are based on the absolute difference between the hourly-adjusted UO and a simple hourly summation of UO. Measurements charted on the hour were included with the previous time interval.
mean(adj_uo_diff$no_diff)
## [1] 0.8368248

 

Hourly UO Per Kilogram

S9_c <- uo_ml_kg_hr %>%
  dplyr::summarise(N = n(),
                   Mean = round(mean(ML_KG_HR),2),
                   SD = round(sd(ML_KG_HR),2),
                   '5th' = round(quantile(ML_KG_HR, 0.05),2),
                   '10th' = round(quantile(ML_KG_HR, 0.1),2),
                   '25th' = round(quantile(ML_KG_HR, 0.25),2),
                   '50th' = round(quantile(ML_KG_HR, 0.50),2),
                   '75th' = round(quantile(ML_KG_HR, 0.75),2),
                   '95th' = round(quantile(ML_KG_HR, 0.95),2),
                   Min = round(min(ML_KG_HR),2),
                   Max = round(max(ML_KG_HR),2)
  ) %>% gt() %>%
  fmt_number(use_seps = TRUE, decimals = 2)

S9_c
N Mean SD 5th 10th 25th 50th 75th 95th Min Max
4,812,905.00 1.16 3.46 0.10 0.20 0.41 0.74 1.35 3.31 0.00 850.00
mean_log <- log(mean(uo_ml_kg_hr$ML_KG_HR))
sd_log <- log(sd(uo_ml_kg_hr$ML_KG_HR))
S9_d <- ggplot() + 
  xlim(-1, 10) + 
  geom_histogram(aes(x = ML_KG_HR
                     # , y =..density..
                     ), data=uo_ml_kg_hr, binwidth = 0.05) + 
  # stat_function(fun = dlnorm, args = list(meanlog = mean_log, sdlog = sd_log, log = FALSE), size=1, color='gray') +
  labs(
        # title = "Hourly-Adjusted UO per Kilogram",
        x = "Hourly volume to kg (ml/hr/kg)",
        y = "Frequency"
      ) +
      theme(
        plot.title = element_text(color = "#0099F8", size = 16, face = "bold"),
        plot.subtitle = element_text(size = 10, face = "bold"),
        plot.caption = element_text(face = "italic")
      )

S9_d

# save(all_rows_count, 
#      distinct_time_item_patient_rows_count, 
#      S2_a,
#      S3a,
#      S4_a, S4_b, S4_c, S4_d, S4_e, S4_f,
#      S6_a, S6_b,
#      S7_a, S7_b, S7_c, S7_d, 
#      S8_a, S8_b, S8_c, S8_d, S8_e, S8_f,
#      S9_a, S9_b, S9_c, S9_d, 
#      file = "s_data.Rda")
mimic_uo_rate_true <- uo_rate_true
mimic_hourly_uo <- hourly_uo
mimic_raw_uo_eligible <- raw_uo_eligible

save(all_rows_count, 
     distinct_time_item_patient_rows_count, 
     S2_a,
     S3a,
     S4_a, S4_b, S4_c, S4_d, S4_e, S4_f,
     S6_a, S6_b,
     S7_a, S7_b, S7_c, S7_d, 
     S8_a, S8_b, S8_c, S8_d, S8_e, S8_f,
     S9_a, S9_b, S9_c, S9_d, 
     S11,
     mimic_uo_rate_true,
     mimic_hourly_uo,
     mimic_raw_uo_eligible,
     file = "s_data.Rda")

Performance analysis

describing the prevalnce of oliguric-AKI upon admission

aki_epi %>%
  transmute(
    prevalnce_admit = first_kdigo_uo,
    Incidence_first_day = ifelse(first_kdigo_uo == 0, !is.na(max_uo_stage), NA),
    Incidence_first_day_with_stage = ifelse(first_kdigo_uo == 0 & max_uo_stage > 0, max_uo_stage, NA)
  ) %>%
  tbl_summary(
    missing = "no",
    label = list(
      prevalnce_admit ~ "Prevalence of oliguric-AKI at admission",
      Incidence_first_day ~ "Incidence of newly diagnosed AKI on the first day ",
      Incidence_first_day_with_stage ~ "Maximum KDIGO staging"
    )
  )
Characteristic N = 45,9851
Prevalence of oliguric-AKI at admission 10,014 (22%)
Incidence of newly diagnosed AKI on the first day 13,303 (37%)
Maximum KDIGO staging
    1 6,316 (47%)
    2 6,272 (47%)
    3 715 (5.4%)
1 n (%)
akis_excluded <- aki_epi %>%
  filter(first_kdigo_uo == 0 & max_uo_stage > 0) %>%
  transmute(AKI_ID = first_aki_id) %>%
  left_join(akis, by = "AKI_ID")

akis_excluded$PEAK_UO_STAGE <- as.character(akis_excluded$PEAK_UO_STAGE)

aki_uo_analysis <- left_join(akis_excluded, uo_ml_kg_hr, by = "STAY_ID") %>%
  drop_na(AKI_START, 
          TIME_INTERVAL_FINISH, 
          PEAK_UO_STAGE) %>%
  select(AKI_ID,
         STAY_ID,
         PEAK_UO_STAGE,
         AKI_START,
         TIME_INTERVAL_FINISH,
         UO_KG = ML_KG_HR
         ) %>%
  mutate(TIME = as.double(difftime(TIME_INTERVAL_FINISH, 
                                   AKI_START, 
                                   units = c("hour")))) %>%
  filter(TIME >= -48 & TIME <= 48)

aki_creat_analysis <- left_join(akis_excluded, creat_diff %>% select(-STAY_ID), by = "HADM_ID") %>%
  select(AKI_ID,
         STAY_ID,
         PEAK_UO_STAGE,
         AKI_START,
         CHARTTIME,
         CREAT,
         SCR_BASELINE,
         CREAT_BASLINE_DIFF,
         CREAT_BASLINE_RATIO,
         CREAT_LOWEST7_DIFF,
         CREAT_LOWEST7_RATIO
         ) %>%
  mutate(AKI_TO_CREAT = as.double(difftime(CHARTTIME, 
                                   AKI_START, 
                                   units = c("mins"))) / 60) %>%
  filter(AKI_TO_CREAT >= -72 & AKI_TO_CREAT <= 72)

First Oliguric-AKI Events

Number of identified first oliguric-AKI events in hospitalization stratified by maximum stage:

akis_excluded %>%
  select(PEAK_UO_STAGE) %>%
  mutate(PEAK_UO_STAGE = as.factor(PEAK_UO_STAGE)) %>%
  tbl_summary()
Characteristic N = 13,3031
PEAK_UO_STAGE
    1 6,316 (47%)
    2 6,272 (47%)
    3 715 (5.4%)
1 n (%)

table 1 for those ICU stays, stratified by max kdigo-uo stage:

akis_excluded %>%
  select(STAY_ID, PEAK_UO_STAGE) %>%
  left_join(table_1, by = "STAY_ID") %>%
  select(
    PEAK_UO_STAGE,
    admission_age,
    weight_admit,
    gender,
    race,
    sofa_first_day,
    charlson_comorbidity_index,
    ckd,
    creat_first,
    # scr_baseline,
    hospital_days,
    icu_days,
    rrt_binary,
    hospital_expire_flag
  ) %>%
  tbl_summary(
    by = PEAK_UO_STAGE,
    type = list(
      c(hospital_expire_flag,
        ckd,
        rrt_binary) ~ "dichotomous",
      c(admission_age,
        weight_admit,
        creat_first,
        # scr_baseline
        ) ~ "continuous"
    ),
    statistic = c(admission_age,
                  weight_admit,
                  creat_first,
                  # scr_baseline
                  ) ~ "{mean} ({sd})",
    missing = "no",
    missing_text = "-",
    digits = list(hospital_days ~ c(1, 1)),
    label = list(
      admission_age ~ "Age at Hospital Admission, years",
      gender ~ "Gender",
      weight_admit ~ "Weight at ICU Admission, kg",
      charlson_comorbidity_index ~ "CCI Score",
      sofa_first_day ~ "SOFA Score at ICU Admission",
      ckd ~ "CKD, Stage 1-4",
      creat_first ~ "First ICU Creatinine, mg/dL",
      # scr_baseline ~ "Baseline Serum Creatinine, mg/dL",
      race ~ "Ethnicity",
      icu_days ~ "Time in ICU, days",
      hospital_days ~ "Time in hospital, days",
      rrt_binary ~ "Renal replacement therapy",
      hospital_expire_flag ~ "Mortality"
    ) 
  ) %>%
  add_p()
Characteristic 1, N = 6,3161 2, N = 6,2721 3, N = 7151 p-value2
Age at Hospital Admission, years 67 (16) 68 (15) 68 (16) 0.003
Weight at ICU Admission, kg 82 (21) 86 (23) 88 (29) <0.001
Gender


<0.001
    F 2,618 (41%) 2,559 (41%) 347 (49%)
    M 3,698 (59%) 3,713 (59%) 368 (51%)
Ethnicity


<0.001
    African American 471 (8.6%) 474 (8.7%) 84 (14%)
    Asian 151 (2.8%) 105 (1.9%) 14 (2.3%)
    Caucasian 4,409 (81%) 4,445 (82%) 468 (77%)
    Hispanic 181 (3.3%) 159 (2.9%) 17 (2.8%)
    Other 240 (4.4%) 241 (4.4%) 25 (4.1%)
SOFA Score at ICU Admission 4 (2, 6) 4 (2, 6) 5 (2, 8) <0.001
CCI Score 4 (3, 6) 5 (3, 7) 6 (4, 8) <0.001
CKD, Stage 1-4 899 (100%) 958 (100%) 153 (100%)
First ICU Creatinine, mg/dL 1.08 (0.77) 1.11 (0.90) 1.42 (1.29) <0.001
Time in hospital, days 7.0 (4.0, 11.0) 7.0 (4.0, 11.0) 9.0 (5.0, 15.0) <0.001
Time in ICU, days 1.9 (1.2, 3.5) 2.2 (1.3, 3.9) 3.8 (2.5, 6.8) <0.001
Renal replacement therapy 122 (1.9%) 133 (2.1%) 106 (15%) <0.001
Mortality 448 (7.1%) 491 (7.8%) 171 (24%) <0.001
1 Mean (SD); n (%); Median (IQR)
2 Kruskal-Wallis rank sum test; Pearson’s Chi-squared test
mimic_uo_figure <- aki_uo_analysis %>% 
ggplot(aes(TIME, UO_KG, color=PEAK_UO_STAGE, fill=PEAK_UO_STAGE))  + 
           # linetype=PEAK_UO_STAGE))  + 
  geom_hline(yintercept=0.3, size = 0.3, color = "#cccccc") +
  geom_hline(yintercept=0.5, size = 0.3, color = "#cccccc") +
  geom_vline(xintercept=0, size = 0.3, color = "black", linetype = "dashed") +
  stat_summary(fun = median, geom="line") +
  scale_x_continuous(breaks = seq(-24, 48, by=6)) +
  scale_y_continuous(breaks = c(0, 0.3, 0.5)) +
  coord_cartesian(xlim = c(-12, 24), ylim = c(0, 1.7)) +
  # xlim(-24, 48) +
  stat_summary(fun.min = function(z) { quantile(z,0.25) },
               fun.max = function(z) { quantile(z,0.75) },
               geom="ribbon", colour = NA, alpha=0.2) +
  labs(x="Time around AKI onset (hour)", y = "Urine output (ml/kg/hr)", 
       # title="Hourly Urine Output at the Onset of Oliguric AKI Events",
       color="Maximum KDIGO-UO stage", fill="Maximum KDIGO-UO stage") + 
       # linetype="Peak AKI stage") + 
  theme_classic() + # remove panel background and gridlines
  # annotate("rect", xmin = -24, xmax = 48, ymin = 0, ymax = 0.5,
  #          alpha = .1) +
  # annotate("rect", xmin = -24, xmax = 48, ymin = 0, ymax = 0.3,
  #          alpha = .1) +
  scale_colour_manual(values=c("#00a087ff", "#4dbbd5ff", "#e64b35ff")
                      # ,labels=c("1 (N=12,911)","2 (N=10,619)","3 (N=1,300)")
                      ) +
  scale_fill_manual(values=c("#00a087ff", "#4dbbd5ff", "#e64b35ff")
                    # ,labels=c("1 (N=12,911)","2 (N=10,619)","3 (N=1,300)")
                      ) +
  theme(
    legend.position = "bottom",
    plot.title = element_text(color = "#0099F8", size = 16, face = "bold"),
    plot.subtitle = element_text(size = 10, face = "bold"),
    plot.caption = element_text(face = "italic")
  )

mimic_uo_figure

 

Survival Analysis

km_fit <- survfit2(Surv(FIRST_AKI_TO_DEATH_OR_DISCH, HADM_DEATH_FLAG) ~ PEAK_UO_STAGE, data = akis_excluded)

mimic_survival_figure <- km_fit %>%
ggsurvfit(linewidth = 1) +
  add_confidence_interval() +
  add_quantile() +
  scale_ggsurvfit(x_scales = list(breaks = seq(0, 30, by = 5))) +
  coord_cartesian(xlim = c(0, 30)) +
  theme_classic() +
  labs(x="Days", y = "Survival", 
       # title="30-Days Survival Analysis",
       # subtitle = "Stratified by first hospitalization AKI event peak staging", 
       color='Maximum KDIGO-UO stage', fill='Maximum KDIGO-UO stage') +
  scale_colour_manual(values=c("#00a087ff", "#4dbbd5ff", "#e64b35ff"),
                    labels=c("1","2","3")) +
  scale_fill_manual(values=c("#00a087ff", "#4dbbd5ff", "#e64b35ff"),
                    labels=c("1","2","3")) +
  theme(legend.position = "bottom",
        plot.title = element_text(color = "#0099F8", size = 16, face = "bold"),
        plot.subtitle = element_text(size = 10, face = "bold"))
  # + add_pvalue(caption = "Log-rank {p.value}")

mimic_survival_figure

table of survival probabilities:

survfit2(Surv(FIRST_AKI_TO_DEATH_OR_DISCH, HADM_DEATH_FLAG) ~ 1,
           data = akis_excluded) %>% tbl_survfit(times = c(7, 30),
                                                 label = "Maximum KDIGO-UO stage",
                                                 label_header = "**Day {time}**")
Characteristic Day 7 Day 30
Maximum KDIGO-UO stage 93% (92%, 93%) 75% (73%, 77%)
mimic_survival_table <-
  survfit2(Surv(FIRST_AKI_TO_DEATH_OR_DISCH, HADM_DEATH_FLAG) ~ PEAK_UO_STAGE,
           data = akis_excluded) %>% tbl_survfit(times = c(7, 30),
                                                 label = "Maximum KDIGO-UO stage",
                                                 label_header = "**Day {time}**")
mimic_survival_table
Characteristic Day 7 Day 30
Maximum KDIGO-UO stage

    1 94% (93%, 94%) 77% (74%, 80%)
    2 93% (92%, 94%) 76% (73%, 80%)
    3 82% (79%, 86%) 59% (53%, 66%)

Log rank for each pair:

survdiff(Surv(FIRST_AKI_TO_DEATH_OR_DISCH, HADM_DEATH_FLAG) ~ PEAK_UO_STAGE, 
         data = akis_excluded)
## Call:
## survdiff(formula = Surv(FIRST_AKI_TO_DEATH_OR_DISCH, HADM_DEATH_FLAG) ~ 
##     PEAK_UO_STAGE, data = akis_excluded)
## 
##                    N Observed Expected (O-E)^2/E (O-E)^2/V
## PEAK_UO_STAGE=1 6316      448    512.8      8.19      15.2
## PEAK_UO_STAGE=2 6272      491    517.3      1.33       2.5
## PEAK_UO_STAGE=3  715      171     79.9    103.75     112.5
## 
##  Chisq= 114  on 2 degrees of freedom, p= <2e-16
akis_excluded_non_1 <- akis_excluded %>%
  filter(PEAK_UO_STAGE != 1)
survdiff(Surv(FIRST_AKI_TO_DEATH_OR_DISCH, HADM_DEATH_FLAG) ~ PEAK_UO_STAGE, 
         data = akis_excluded_non_1)
## Call:
## survdiff(formula = Surv(FIRST_AKI_TO_DEATH_OR_DISCH, HADM_DEATH_FLAG) ~ 
##     PEAK_UO_STAGE, data = akis_excluded_non_1)
## 
##                    N Observed Expected (O-E)^2/E (O-E)^2/V
## PEAK_UO_STAGE=2 6272      491    574.2      12.1        92
## PEAK_UO_STAGE=3  715      171     87.8      78.9        92
## 
##  Chisq= 92  on 1 degrees of freedom, p= <2e-16
akis_excluded_non_2 <- akis_excluded %>%
  filter(PEAK_UO_STAGE != 2)
survdiff(Surv(FIRST_AKI_TO_DEATH_OR_DISCH, HADM_DEATH_FLAG) ~ PEAK_UO_STAGE, 
         data = akis_excluded_non_2)
## Call:
## survdiff(formula = Surv(FIRST_AKI_TO_DEATH_OR_DISCH, HADM_DEATH_FLAG) ~ 
##     PEAK_UO_STAGE, data = akis_excluded_non_2)
## 
##                    N Observed Expected (O-E)^2/E (O-E)^2/V
## PEAK_UO_STAGE=1 6316      448    535.2      14.2       106
## PEAK_UO_STAGE=3  715      171     83.8      90.6       106
## 
##  Chisq= 106  on 1 degrees of freedom, p= <2e-16
akis_excluded_non_3 <- akis_excluded %>%
  filter(PEAK_UO_STAGE != 3)
survdiff(Surv(FIRST_AKI_TO_DEATH_OR_DISCH, HADM_DEATH_FLAG) ~ PEAK_UO_STAGE, 
         data = akis_excluded_non_3)
## Call:
## survdiff(formula = Surv(FIRST_AKI_TO_DEATH_OR_DISCH, HADM_DEATH_FLAG) ~ 
##     PEAK_UO_STAGE, data = akis_excluded_non_3)
## 
##                    N Observed Expected (O-E)^2/E (O-E)^2/V
## PEAK_UO_STAGE=1 6316      448      467     0.811      1.62
## PEAK_UO_STAGE=2 6272      491      472     0.804      1.62
## 
##  Chisq= 1.6  on 1 degrees of freedom, p= 0.2

 

Serum Creatinine Analysis

aki_creat_analysis %>%
ggplot(aes(x=CREAT_BASLINE_DIFF)) + 
    xlim(0, 5) + 
    geom_histogram(binwidth = 0.1)

Number of events for creatinine analysis by max staging::

print("Stage 1:")
## [1] "Stage 1:"
aki_creat_analysis %>% 
  filter(PEAK_UO_STAGE == 1,
         AKI_TO_CREAT >= -24,
         AKI_TO_CREAT <= 48) %>%
  {n_distinct(.$AKI_ID)}
## [1] 6297
print("Stage 2:")
## [1] "Stage 2:"
aki_creat_analysis %>% 
  filter(PEAK_UO_STAGE == 2,
         AKI_TO_CREAT >= -24,
         AKI_TO_CREAT <= 48) %>%
  {n_distinct(.$AKI_ID)}
## [1] 6249
print("Stage 3:")
## [1] "Stage 3:"
aki_creat_analysis %>% 
  filter(PEAK_UO_STAGE == 3,
         AKI_TO_CREAT >= -24,
         AKI_TO_CREAT <= 48) %>%
  {n_distinct(.$AKI_ID)}
## [1] 710
creat_plot_a <- aki_creat_analysis %>% 
  filter(PEAK_UO_STAGE == 1,
         AKI_TO_CREAT >= -24,
         AKI_TO_CREAT <= 48) %>%
  mutate(AKI_TO_CREAT_BIN = cut(AKI_TO_CREAT, 
                                breaks=12, 
                                ordered_result = TRUE,
                                # labels=FALSE
                                )) %>%
ggplot(aes(factor(AKI_TO_CREAT_BIN), CREAT_LOWEST7_DIFF)) +
    geom_boxplot(linetype = "dashed", outlier.shape = NA, color="brown") +
    stat_boxplot(aes(ymin = ..lower.., ymax = ..upper..), outlier.shape = NA, color="brown", fill="orange") +
    stat_boxplot(geom = "errorbar", aes(ymin = ..ymax..), color="brown") +
    stat_boxplot(geom = "errorbar", aes(ymax = ..ymin..), color="brown") +
    stat_summary(fun.y=mean, colour="darkred", geom="point", hape=18, size=2,show_guide = FALSE) +
    stat_summary(fun.y=mean, colour="black", geom="text", size=3, show_guide = FALSE, 
                   vjust=1.8, aes( label=round(..y.., digits=2))) +
    # scale_x_discrete(labels=c('-24      ','-18      ','-12      ','-6      ','0      ','6      ','12      ','18      ','24      ','30      ','36      ','42      ','48      ')) +
    labs(x="Time to AKI start (hours)", y = "Absolute SCr change(mg/dl)") +
    coord_cartesian(ylim = c(-0.1, 3)) +
    theme_classic() + # remove panel background and gridlines
    theme(legend.position = "bottom",
          plot.title = element_text(color = "#0099F8", size = 16, face = "bold"),
          plot.subtitle = element_text(size = 10, face = "bold"),
          # axis.text.x = element_text(margin = margin(t = 2),
          #                            hjust="1")
          )

creat_plot_a

creat_plot_d <- aki_creat_analysis %>% 
  filter(PEAK_UO_STAGE == 1,
         AKI_TO_CREAT >= -24,
         AKI_TO_CREAT <= 48) %>%
  mutate(AKI_TO_CREAT_BIN = cut(AKI_TO_CREAT, 
                                breaks=12, 
                                ordered_result = TRUE)) %>%
ggplot(aes(factor(AKI_TO_CREAT_BIN), CREAT_LOWEST7_RATIO)) +
    geom_boxplot(linetype = "dashed", outlier.shape = NA, color="brown") +
    stat_boxplot(aes(ymin = ..lower.., ymax = ..upper..), outlier.shape = NA, color="brown", fill="orange") +
    stat_boxplot(geom = "errorbar", aes(ymin = ..ymax..), color="brown") +
    stat_boxplot(geom = "errorbar", aes(ymax = ..ymin..), color="brown") +
    stat_summary(fun.y=mean, colour="darkred", geom="point", hape=18, size=2,show_guide = FALSE) +
    stat_summary(fun.y=mean, colour="black", geom="text", size=3, show_guide = FALSE, 
                   vjust=1.8, aes( label=round(..y.., digits=2))) +
    labs(x="Time to AKI start (hours)", y = "Relative SCr change") +
    coord_cartesian(ylim = c(1.01, 3)) +
    theme_classic() + # remove panel background and gridlines
    theme(legend.position = "bottom",
          plot.title = element_text(color = "#0099F8", size = 16, face = "bold"),
          plot.subtitle = element_text(size = 10, face = "bold"))
creat_plot_d

creat_plot_b <- aki_creat_analysis %>% 
  filter(PEAK_UO_STAGE == 2,
         AKI_TO_CREAT >= -24,
         AKI_TO_CREAT <= 48) %>%
  mutate(AKI_TO_CREAT_BIN = cut(AKI_TO_CREAT, 
                                breaks=12, 
                                ordered_result = TRUE,
                                # labels=FALSE
                                )) %>%
ggplot(aes(factor(AKI_TO_CREAT_BIN), CREAT_LOWEST7_DIFF)) +
    geom_boxplot(linetype = "dashed", outlier.shape = NA, color="brown") +
    stat_boxplot(aes(ymin = ..lower.., ymax = ..upper..), outlier.shape = NA, color="brown", fill="orange") +
    stat_boxplot(geom = "errorbar", aes(ymin = ..ymax..), color="brown") +
    stat_boxplot(geom = "errorbar", aes(ymax = ..ymin..), color="brown") +
    stat_summary(fun.y=mean, colour="darkred", geom="point", hape=18, size=2,show_guide = FALSE) +
    stat_summary(fun.y=mean, colour="black", geom="text", size=3, show_guide = FALSE, 
                   vjust=1.8, aes( label=round(..y.., digits=2))) +
    # scale_x_discrete(labels=c('-24      ','-18      ','-12      ','-6      ','0      ','6      ','12      ','18      ','24      ','30      ','36      ','42      ','48      ')) +
    labs(x="Time to AKI start (hours)", y = "Absolute SCr change(mg/dl)") +
    coord_cartesian(ylim = c(-0.1, 3)) +
    theme_classic() + # remove panel background and gridlines
    theme(legend.position = "bottom",
          plot.title = element_text(color = "#0099F8", size = 16, face = "bold"),
          plot.subtitle = element_text(size = 10, face = "bold"),
          # axis.text.x = element_text(margin = margin(t = 2),
          #                            hjust="1")
          )

creat_plot_b

creat_plot_e <- aki_creat_analysis %>% 
  filter(PEAK_UO_STAGE == 2,
         AKI_TO_CREAT >= -24,
         AKI_TO_CREAT <= 48) %>%
  mutate(AKI_TO_CREAT_BIN = cut(AKI_TO_CREAT, 
                                breaks=12, 
                                ordered_result = TRUE)) %>%
ggplot(aes(factor(AKI_TO_CREAT_BIN), CREAT_LOWEST7_RATIO)) +
    geom_boxplot(linetype = "dashed", outlier.shape = NA, color="brown") +
    stat_boxplot(aes(ymin = ..lower.., ymax = ..upper..), outlier.shape = NA, color="brown", fill="orange") +
    stat_boxplot(geom = "errorbar", aes(ymin = ..ymax..), color="brown") +
    stat_boxplot(geom = "errorbar", aes(ymax = ..ymin..), color="brown") +
    stat_summary(fun.y=mean, colour="darkred", geom="point", hape=18, size=2,show_guide = FALSE) +
    stat_summary(fun.y=mean, colour="black", geom="text", size=3, show_guide = FALSE, 
                   vjust=1.8, aes( label=round(..y.., digits=2))) +
    labs(x="Time to AKI start (hours)", y = "Relative SCr change") +
    coord_cartesian(ylim = c(1.01, 3)) +
    theme_classic() + # remove panel background and gridlines
    theme(legend.position = "bottom",
          plot.title = element_text(color = "#0099F8", size = 16, face = "bold"),
          plot.subtitle = element_text(size = 10, face = "bold"))
creat_plot_e

creat_plot_c <- aki_creat_analysis %>% 
  filter(PEAK_UO_STAGE == 3,
         AKI_TO_CREAT >= -24,
         AKI_TO_CREAT <= 48) %>%
  mutate(AKI_TO_CREAT_BIN = cut(AKI_TO_CREAT, 
                                breaks=12, 
                                ordered_result = TRUE,
                                # labels=FALSE
                                )) %>%
ggplot(aes(factor(AKI_TO_CREAT_BIN), CREAT_LOWEST7_DIFF)) +
    geom_boxplot(linetype = "dashed", outlier.shape = NA, color="brown") +
    stat_boxplot(aes(ymin = ..lower.., ymax = ..upper..), outlier.shape = NA, color="brown", fill="orange") +
    stat_boxplot(geom = "errorbar", aes(ymin = ..ymax..), color="brown") +
    stat_boxplot(geom = "errorbar", aes(ymax = ..ymin..), color="brown") +
    stat_summary(fun.y=mean, colour="darkred", geom="point", hape=18, size=2,show_guide = FALSE) +
    stat_summary(fun.y=mean, colour="black", geom="text", size=3, show_guide = FALSE, 
                   vjust=1.8, aes( label=round(..y.., digits=2))) +
    # scale_x_discrete(labels=c('-24      ','-18      ','-12      ','-6      ','0      ','6      ','12      ','18      ','24      ','30      ','36      ','42      ','48      ')) +
    labs(x="Time to AKI start (hours)", y = "Absolute SCr change(mg/dl)") +
    coord_cartesian(ylim = c(-0.1, 3)) +
    theme_classic() + # remove panel background and gridlines
    theme(legend.position = "bottom",
          plot.title = element_text(color = "#0099F8", size = 16, face = "bold"),
          plot.subtitle = element_text(size = 10, face = "bold"),
          # axis.text.x = element_text(margin = margin(t = 2),
          #                            hjust="1")
          )

creat_plot_c

creat_plot_f <- aki_creat_analysis %>% 
  filter(PEAK_UO_STAGE == 3,
         AKI_TO_CREAT >= -24,
         AKI_TO_CREAT <= 48) %>%
  mutate(AKI_TO_CREAT_BIN = cut(AKI_TO_CREAT, 
                                breaks=12, 
                                ordered_result = TRUE)) %>%
ggplot(aes(factor(AKI_TO_CREAT_BIN), CREAT_LOWEST7_RATIO)) +
    geom_boxplot(linetype = "dashed", outlier.shape = NA, color="brown") +
    stat_boxplot(aes(ymin = ..lower.., ymax = ..upper..), outlier.shape = NA, color="brown", fill="orange") +
    stat_boxplot(geom = "errorbar", aes(ymin = ..ymax..), color="brown") +
    stat_boxplot(geom = "errorbar", aes(ymax = ..ymin..), color="brown") +
    stat_summary(fun.y=mean, colour="darkred", geom="point", hape=18, size=2,show_guide = FALSE) +
    stat_summary(fun.y=mean, colour="black", geom="text", size=3, show_guide = FALSE, 
                   vjust=1.8, aes( label=round(..y.., digits=2))) +
    labs(x="Time to AKI start (hours)", y = "Relative SCr change") +
    coord_cartesian(ylim = c(1.01, 3)) +
    theme_classic() + # remove panel background and gridlines
    theme(legend.position = "bottom",
          plot.title = element_text(color = "#0099F8", size = 16, face = "bold"),
          plot.subtitle = element_text(size = 10, face = "bold"))
creat_plot_f

temp1 <- ggarrange(
  creat_plot_a +
    theme(
      axis.title.x = element_blank()
    ),
  creat_plot_b +
    labs(y = " ") +
    theme(
      axis.text.y = element_blank(),
      axis.ticks.y = element_blank(),
      axis.title.x = element_blank()
    ),
  creat_plot_c +
    labs(y = " ") +
    theme(
      axis.text.y = element_blank(),
      axis.ticks.y = element_blank(),
      axis.title.x = element_blank()
    ),
  labels = c("a", "b", "c"),
  ncol = 3,
  nrow = 1
) 

temp2 <- ggarrange(
  creat_plot_d +
    labs(x=" ") +
    theme(
    ),
  creat_plot_e +
    labs(y=" ") +
    theme(
      axis.text.y = element_blank(),
      axis.ticks.y = element_blank()
    ),
  creat_plot_f +
    labs(x=" ", y = " ") +
    theme(
      axis.text.y = element_blank(),
      axis.ticks.y = element_blank()
    ),
  labels = c("d", "e", "f"),
  ncol = 3,
  nrow = 1
) 

ggarrange(
  temp1,
  temp2,
  ncol = 1,
  nrow = 2
)

mimic_aki_epi <- aki_epi
mimic_akis <- akis
mimic_t1a <- t1a
mimic_t1b <- t1b
mimic_table_1 <- table_1
mimic_uo_rate <- uo_rate

save(mimic_aki_epi,
     mimic_akis,
     mimic_t1a,
     mimic_t1b,
     mimic_table_1,
     mimic_uo_rate,
     mimic_uo_figure,
     mimic_survival_figure,
     mimic_survival_table,
     file = "paper_mimic.Rda")

Technical Details

R Session Info:

sessionInfo()
## R version 4.3.1 (2023-06-16)
## Platform: aarch64-apple-darwin20 (64-bit)
## Running under: macOS Sonoma 14.3.1
## 
## Matrix products: default
## BLAS:   /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRblas.0.dylib 
## LAPACK: /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRlapack.dylib;  LAPACK version 3.11.0
## 
## locale:
## [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
## 
## time zone: Asia/Jerusalem
## tzcode source: internal
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
##  [1] gt_0.10.0        ggsurvfit_0.3.0  ggsci_3.0.0      gtsummary_1.7.2 
##  [5] nortest_1.0-4    survminer_0.4.9  ggpubr_0.6.0     survival_3.5-5  
##  [9] rmdformats_1.0.4 kableExtra_1.3.4 broom_1.0.5      quantreg_5.95   
## [13] SparseM_1.81     rlang_1.1.1      ggforce_0.4.1    ggpmisc_0.5.3   
## [17] ggpp_0.5.2       scales_1.2.1     ggbreak_0.1.2    psych_2.3.6     
## [21] finalfit_1.0.6   reshape2_1.4.4   lubridate_1.9.2  forcats_1.0.0   
## [25] stringr_1.5.0    dplyr_1.1.2      purrr_1.0.1      readr_2.1.4     
## [29] tidyr_1.3.0      tibble_3.2.1     ggplot2_3.4.2    tidyverse_2.0.0 
## [33] bigrquery_1.5.0  DBI_1.1.3        pacman_0.5.1    
## 
## loaded via a namespace (and not attached):
##   [1] RColorBrewer_1.1-3   rstudioapi_0.14      jsonlite_1.8.5      
##   [4] shape_1.4.6          magrittr_2.0.3       jomo_2.7-6          
##   [7] farver_2.1.1         nloptr_2.0.3         rmarkdown_2.22      
##  [10] fs_1.6.2             vctrs_0.6.3          minqa_1.2.5         
##  [13] askpass_1.1          rstatix_0.7.2        webshot_0.5.5       
##  [16] htmltools_0.5.5      polynom_1.4-1        curl_5.2.0          
##  [19] gridGraphics_0.5-1   mitml_0.4-5          sass_0.4.6          
##  [22] bslib_0.5.0          plyr_1.8.8           zoo_1.8-12          
##  [25] cachem_1.0.8         commonmark_1.9.0     lifecycle_1.0.3     
##  [28] iterators_1.0.14     pkgconfig_2.0.3      Matrix_1.5-4.1      
##  [31] R6_2.5.1             fastmap_1.1.1        digest_0.6.31       
##  [34] aplot_0.1.10         colorspace_2.1-0     patchwork_1.1.2     
##  [37] labeling_0.4.2       fansi_1.0.4          km.ci_0.5-6         
##  [40] timechange_0.2.0     mgcv_1.8-42          httr_1.4.6          
##  [43] polyclip_1.10-4      abind_1.4-5          compiler_4.3.1      
##  [46] gargle_1.5.1         bit64_4.0.5          withr_2.5.0         
##  [49] backports_1.4.1      carData_3.0-5        highr_0.10          
##  [52] ggsignif_0.6.4       pan_1.8              MASS_7.3-60         
##  [55] openssl_2.0.6        rappdirs_0.3.3       tools_4.3.1         
##  [58] nnet_7.3-19          glue_1.6.2           nlme_3.1-162        
##  [61] grid_4.3.1           generics_0.1.3       gtable_0.3.3        
##  [64] tzdb_0.4.0           KMsurv_0.1-5         data.table_1.15.0   
##  [67] hms_1.1.3            xml2_1.3.4           car_3.1-2           
##  [70] utf8_1.2.3           markdown_1.7         foreach_1.5.2       
##  [73] pillar_1.9.0         yulab.utils_0.0.6    splines_4.3.1       
##  [76] tweenr_2.0.2         lattice_0.21-8       bit_4.0.5           
##  [79] tidyselect_1.2.0     knitr_1.43           gridExtra_2.3       
##  [82] bookdown_0.37        svglite_2.1.1        xfun_0.39           
##  [85] brio_1.1.3           stringi_1.7.12       ggfun_0.1.1         
##  [88] yaml_2.3.7           boot_1.3-28.1        evaluate_0.21       
##  [91] codetools_0.2-19     ggplotify_0.1.1      cli_3.6.1           
##  [94] rpart_4.1.19         xtable_1.8-4         systemfonts_1.0.4   
##  [97] munsell_0.5.0        jquerylib_0.1.4      survMisc_0.5.6      
## [100] Rcpp_1.0.10          parallel_4.3.1       MatrixModels_0.5-1  
## [103] lme4_1.1-33          glmnet_4.1-7         broom.helpers_1.13.0
## [106] viridisLite_0.4.2    cowplot_1.1.1        rvest_1.0.3         
## [109] mnormt_2.1.1         mice_3.16.0